#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include "c-client.h"
#include "imap4r1.h"


//using namespace std;

void status (MAILSTREAM *stream);
int main();

void mm_searched (MAILSTREAM *stream,unsigned long number)
{
}

void mm_exists (MAILSTREAM *stream,unsigned long number)
{
}


void mm_expunged (MAILSTREAM *stream,unsigned long number)
{
}


void mm_flags (MAILSTREAM *stream,unsigned long number)
{
}


void mm_notify (MAILSTREAM *stream,char *string,long errflg)
{
  mm_log (string,errflg);
}

void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
{
  putchar (' ');
  if (delimiter) putchar (delimiter);
  else fputs ("NIL",stdout);
  putchar (' ');
  fputs (mailbox,stdout);
  if (attributes & LATT_NOINFERIORS) fputs (", no inferiors",stdout);
  if (attributes & LATT_NOSELECT) fputs (", no select",stdout);
  if (attributes & LATT_MARKED) fputs (", marked",stdout);
  if (attributes & LATT_UNMARKED) fputs (", unmarked",stdout);
  putchar ('\n');
}


void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
{
  putchar (' ');
  if (delimiter) putchar (delimiter);
  else fputs ("NIL",stdout);
  putchar (' ');
  fputs (mailbox,stdout);
  if (attributes & LATT_NOINFERIORS) fputs (", no inferiors",stdout);
  if (attributes & LATT_NOSELECT) fputs (", no select",stdout);
  if (attributes & LATT_MARKED) fputs (", marked",stdout);
  if (attributes & LATT_UNMARKED) fputs (", unmarked",stdout);
  putchar ('\n');
}

void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
{
  printf (" Mailbox %s",mailbox);
  if (status->flags & SA_MESSAGES) printf (", %lu messages",status->messages);
  if (status->flags & SA_RECENT) printf (", %lu recent",status->recent);
  if (status->flags & SA_UNSEEN) printf (", %lu unseen",status->unseen);
  if (status->flags & SA_UIDVALIDITY) printf (", %lu UID validity",
                                              status->uidvalidity);
  if (status->flags & SA_UIDNEXT) printf (", %lu next UID",status->uidnext);
  printf ("\n");
}

void mm_log (char *string,long errflg)
{
  switch ((short) errflg) {
  case NIL:
    printf ("[%s]\n",string);
    break;
  case PARSE:
  case WARN:
    printf ("%%%s\n",string);
    break;
  case ERROR:
    printf ("?%s\n",string);
    break;
  }
}

void mm_dlog (char *string)
{
  puts (string);
}



void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
{

	char* curhst = mylocalhost();
	char* curusr = myusername ();
	char *s,tmp[MAILTMPLEN];
  if (curhst) fs_give ((void **) &curhst);
  curhst = (char *) fs_get (1+strlen (mb->host));
  strcpy (curhst,mb->host);
  sprintf (s = tmp,"{%s/%s",mb->host,mb->service);
  if (*mb->user) sprintf (tmp+strlen (tmp),"/user=%s",strcpy (user,mb->user));
  if (*mb->authuser) sprintf (tmp+strlen (tmp),"/authuser=%s",mb->authuser);
  if (*mb->user) strcat (s = tmp,"} password:");
  else {
    printf ("%s} username: ",tmp);
    fgets (user,NETMAXUSER-1,stdin);
    user[NETMAXUSER-1] = '\0';
    if (s = strchr (user,'\n')) *s = '\0';
    s = "password: ";
  }
  if (curusr) fs_give ((void **) &curusr);
  curusr = cpystr (user);
  strcpy (pwd,getpass (s));

}


void mm_critical (MAILSTREAM *stream)
{
}


void mm_nocritical (MAILSTREAM *stream)
{
}


long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
{
#if UNIXLIKE
  kill (getpid (),SIGSTOP);
#else
  abort ();
#endif
  return NIL;
}


void mm_fatal (char *string)
{
  printf ("?%s\n",string);
}

int main ()
{


	MAILSTREAM *stream = NIL;
	STRINGLIST *lines = mail_newstringlist ();
	STRINGLIST *cur = lines;
	char* curusr = myusername ();
	printf("%s\n", curusr);
	char* curhst = cpystr (mylocalhost ());;
	printf("%s\n", curhst);
	char* mailbox = "INBOX";
	long last = 7;


//	mail_list (NIL,NIL,"%");
	stream = mail_open (stream,mailbox,NIL);


	mail_check (stream);
	status(stream);


	if (last && (last <= stream->nmsgs)) {
        STRINGLIST *lines = mail_newstringlist ();
        STRINGLIST *cur = lines;
        cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
                                           cpystr ("Date")));
        cur = cur->next = mail_newstringlist ();
        cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
                                           cpystr ("From")));
        cur = cur->next = mail_newstringlist ();
        cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
                                           cpystr (">From")));
        cur = cur->next = mail_newstringlist ();
        cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
                                           cpystr ("Subject")));
        cur = cur->next = mail_newstringlist ();
        cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
                                           cpystr ("To")));
        cur = cur->next = mail_newstringlist ();
        cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
                                           cpystr ("cc")));
        cur = cur->next = mail_newstringlist ();
        cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
                                           cpystr ("Newsgroups")));
        printf ("%s",mail_fetchheader_full (stream,last,lines,NIL,NIL));
        puts (mail_fetchtext (stream,last));
        mail_free_stringlist (&lines);
      }

	
	return 0;
}

void status (MAILSTREAM *stream)
{
  unsigned long i;
  char *s,date[MAILTMPLEN];
  THREADER *thr;
  AUTHENTICATOR *auth;
  rfc822_date (date);
  puts (date);
  if (stream) {
    if (stream->mailbox)
      printf (" %s mailbox: %s, %lu messages, %lu recent\n",
	      stream->dtb->name,stream->mailbox,stream->nmsgs,stream->recent);
    else puts ("%No mailbox is open on this stream");
    if (stream->user_flags[0]) {
      printf ("Keywords: %s",stream->user_flags[0]);
      for (i = 1; i < NUSERFLAGS && stream->user_flags[i]; ++i)
	printf (", %s",stream->user_flags[i]);
      puts ("");
    }
    if (!strcmp (stream->dtb->name,"imap")) {
      if (LEVELIMAP4rev1 (stream)) s = "IMAP4rev1 (RFC 3501)";
      else if (LEVEL1730 (stream)) s = "IMAP4 (RFC 1730)";
      else if (LEVELIMAP2bis (stream)) s = "IMAP2bis";
      else if (LEVEL1176 (stream)) s = "IMAP2 (RFC 1176)";
      else s = "IMAP2 (RFC 1064)";
      printf ("%s server %s\n",s,imap_host (stream));
      if (LEVELIMAP4 (stream)) {
	if (i = imap_cap (stream)->auth) {
	  s = "";
	  printf ("Mutually-supported SASL mechanisms:");
	  while (auth = mail_lookup_auth (find_rightmost_bit (&i) + 1)) {
	    printf (" %s",auth->name);
	    if (!strcmp (auth->name,"PLAIN"))
	      s = "\n  [LOGIN will not be listed here if PLAIN is supported]";
	  }
	  puts (s);
	}
	printf ("Supported standard extensions:\n");
	if (LEVELACL (stream)) puts (" Access Control lists (RFC 2086)");
	if (LEVELQUOTA (stream)) puts (" Quotas (RFC 2087)");
	if (LEVELLITERALPLUS (stream))
	  puts (" Non-synchronizing literals (RFC 2088)");
	if (LEVELIDLE (stream)) puts (" IDLE unsolicited update (RFC 2177)");
	if (LEVELMBX_REF (stream)) puts (" Mailbox referrals (RFC 2193)");
	if (LEVELLOG_REF (stream)) puts (" Login referrals (RFC 2221)");
	if (LEVELANONYMOUS (stream)) puts (" Anonymous access (RFC 2245)");
	if (LEVELNAMESPACE (stream)) puts (" Multiple namespaces (RFC 2342)");
	if (LEVELUIDPLUS (stream)) puts (" Extended UID behavior (RFC 2359)");
	if (LEVELSTARTTLS (stream))
	  puts (" Transport Layer Security (RFC 2595)");
	if (LEVELLOGINDISABLED (stream))
	  puts (" LOGIN command disabled (RFC 2595)");
	if (LEVELID (stream))
	  puts (" Implementation identity negotiation (RFC 2971)");
	if (LEVELCHILDREN (stream))
	  puts (" LIST children announcement (RFC 3348)");
	if (LEVELMULTIAPPEND (stream))
	  puts (" Atomic multiple APPEND (RFC 3502)");
	if (LEVELBINARY (stream))
	  puts (" Binary body content (RFC 3516)");
	if (LEVELUNSELECT (stream)) puts (" Mailbox unselect (RFC 3691)");
	if (LEVELURLAUTH (stream))
	  puts (" URL authenticated fetch (RFC 4467)");
	if (LEVELCATENATE (stream)) puts (" Catenation (RFC 4469)");
	if (LEVELCONDSTORE (stream)) puts (" Conditional STORE (RFC 4551)");
	if (LEVELESEARCH (stream)) puts (" Extended SEARCH (RFC 4731)");
	puts ("Supported draft extensions:");
	if (LEVELSASLIR (stream)) puts (" SASL initial client response");
	if (LEVELSORT (stream)) puts (" Server-based sorting");
	if (LEVELTHREAD (stream)) {
	  printf (" Server-based threading:");
	  for (thr = imap_cap (stream)->threader; thr; thr = thr->next)
	    printf (" %s",thr->name);
	  putchar ('\n');
	}
	if (LEVELSCAN (stream)) puts (" Mailbox text scan");
	if (i = imap_cap (stream)->extlevel) {
	  printf ("Supported BODYSTRUCTURE extensions:");
	  switch (i) {
	  case BODYEXTLOC: printf (" location");
	  case BODYEXTLANG: printf (" language");
	  case BODYEXTDSP: printf (" disposition");
	  case BODYEXTMD5: printf (" MD5\n");
	  }
	}
      }
      else putchar ('\n');
    }
  }
}
