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

#define TARGET_LEN ((MAX_CHANNEL) > (MAX_NICK) ? (MAX_CHANNEL) : (MAX_NICK))

void who_reply(struct client* c, const struct client* who, const char* channel) {
  client_reply_start(c, "352");
  if(channel) {
    client_puts(c, channel);
  }
  else {
    int i;
    for(i = 0; i < MAX_USER_CHANNELS; i++) {
      if(who->channels[i].active)
        break;
    }
    if(i == MAX_USER_CHANNELS)
      client_puts(c, "*");
    else
      client_puts(c, who->channels[i].s);
  }
  client_puts(c, " unknown unknown ");
  client_puts(c, servername);
  client_puts(c, " ");
  client_puts(c, who->nick);
  client_puts(c, who->is_away ? " G" : " H");
  client_puts(c, " :0 unknown\r\n");
}

void cmd_who(struct client* c, struct token* p, int n) {
  char target[TARGET_LEN];

  if(!n) {
    client_reply_start(c, "461");
    client_puts(c, ":No, no, I won't give you a list of all users!\r\n");
    return;
  }

  str_copyn(target, TARGET_LEN, p[0].s, p[0].len);

  if(target[0] == '#') {
    struct member_list channel;
    int i;

    channel_members(target, &channel);

    if(!channel.n) {
      client_reply_start(c, "403");
      client_puts(c, target);
      client_puts(c, " :No such channel\r\n");
      return;
    }

    for (i = 0; i < channel.n; ++i) {
      who_reply(c, channel.v[i], target);
    }
  }
  else
  {
    struct client* who;

    who = client_find_by_nick(target);

    if(!who) {
      client_reply_start(c, "406");
      client_puts(c, target);
      client_puts(c, " :No such NICK\r\n");
      return;
    }

    who_reply(c, who, 0);
  }

  client_reply_start(c, "315");
  client_puts(c, target);
  client_puts(c, " :End of /WHO list\r\n");
}
