#include "command.h"
#include "client.h"
#include "str.h"
#include "auto_version.h"

static int kosher_nick(const char* s) {
  static const char* beginning = 
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "[]\\`_^{|}";
  static const char* rest = 
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "[]\\`_^{|}"
    "0123456789-";

  if(!str_contains(beginning, *s))
    return 0;

  for(; *s; s++)
    if(!str_contains(rest, *s))
      return 0;

  return 1;
}

void cmd_nick(struct client* c, struct token* p, int n) {
  char nick[MAX_NICK];

  if(!n) {
    client_puts(c, "431 :No nickname given\r\n");
    return;
  }

  str_copyn(nick, MAX_NICK, p[0].s, p[0].len);

  if(!kosher_nick(nick)) {
    client_reply_start(c, "432");
    if(!c->nick[0]) {
      client_put(c, p[0].s, p[0].len);
      client_puts(c, " ");
    }
    client_puts(c, ":Erroneous nickname\r\n");
    return;
  }

  if(client_find_by_nick(nick)) {
    client_reply_start(c, "433");
    if(!c->nick[0]) {
      client_put(c, p[0].s, p[0].len);
      client_puts(c, " ");
    }
    client_puts(c, " :Nickname is already in use\r\n");
    return;
  }

  if(!c->nick[0]) {
    str_copyn(c->nick, MAX_NICK, nick, -1);

    client_reply_start(c, "001");
    client_puts(c, ":Welcome to the Internet Relay Network ");
    client_puts(c, nick);
    client_puts(c, "!unknown@unknown\r\n");

    client_reply_start(c, "002");
    client_puts(c, ":Your host is ");
    client_puts(c, servername);
    client_puts(c, ", running version ");
    client_puts(c, auto_version);
    client_puts(c, "\r\n");

    client_reply_start(c, "003");
    client_puts(c, ":This server was created <unknown>\r\n");

    client_reply_start(c, "004");
    client_puts(c, ":");
    client_puts(c, servername);
    client_puts(c, " ");
    client_puts(c, auto_version);
    client_puts(c, " 0 0\r\n");

    client_reply_start(c, "375");
    client_puts(c, ":- ");
    client_puts(c, servername);
    client_puts(c, " Message of the day - \r\n");
    client_reply_start(c, "372");
    client_puts(c, ":- There is no MOTD.\r\n");
    client_reply_start(c, "376");
    client_puts(c, ":End of MOTD command\r\n");
  }

  else {
    struct member_list members;

    client_listeners(c, &members);
    channel_message_start(&members, c, "NICK");
    channel_puts(&members, nick);
    channel_puts(&members, "\r\n");
    
    str_copyn(c->nick, MAX_NICK, nick, -1);
  }
}
