/*
   ISO 3166 Country Codes program
   --------------------------------------------------------------------
   Country Codes

   Copyright (C) 1999, 2000 Diego Javier Grigna <diego@grigna.com>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "common.h"
#include "protos.h"
#include "tables.h"

int main( int argc, char *argv[])
{
 int domain_flag = 0;
 int ch;

 progname = cc_basename( strdup( argv[ 0]));

 if( argc < 2)
     usage();

 while(( ch = getopt( argc, argv, "ad:")) != EOF){
         switch( ch) {
                case 'a': iso3166_show_all();
                          break;
                case 'd': if( optarg == NULL)
                              usage();
                          domain_name_print( optarg);
                          domain_flag = 1;
                          break;
                default : usage();
         }
 }

 if( !domain_flag && optind >= argc)
     usage();

 if( !domain_flag)
     iso3166_print_heading();

 while( optind < argc)
        if( domain_flag)
            domain_name_print( argv[ optind++]);
        else
            iso3166_show_one( argv[ optind++]);

 putchar( '\n');

 return 0;
}

static void usage( void)
{
 fprintf( stderr, "\nCountry Codes Release %s - ", COCO_VERSION);
 fprintf( stderr, "ISO 3166 Country Codes\n\n");
 fprintf( stderr, "Copyright © 1999, 2000 Diego J. Grigna "
                  "(diego@grigna.com)\n");
 fprintf( stderr, "          © 2017 Johnny A. Solbu "
                  "(johnny@solbu.net\n");
 fprintf( stderr, "This program is free software, covered by the "
                  "GNU General Public License.\n\n");
 fprintf( stderr, "Usage:\n%s [-a] [[code]|[country]|[number]...] "
                  "[-d <domain name>]\n\n", progname);
 fprintf( stderr, "   -a   Show all codes.\n");
 fprintf( stderr, " [code]|[country]|[number]\n");
 fprintf( stderr, "        You could enter a 2 letter (or 3 letter) "
                  "ISO 3166 code,\n");
 fprintf( stderr, "        a country name, or a country number.\n");
 fprintf( stderr, "   -d   <domain name>\n");
 fprintf( stderr, "        Show the domain name country (if possible) and "
                  "try to explain it.\n\n");
 exit( -1);
}

static void iso3166_print_heading( void)
{
 printf( "\nCountry                                          2 "
         "letter  3 letter  Number\n");
 printf( "%s\n", cc_hyp());
}

static void iso3166_print_cc( int index)
{
 printf( "%-52.52s %-2.2s       %-3.3s     %3d\n"
                   , isoccs[ index].country
                   , isoccs[ index].codes2l
                   , isoccs[ index].codes3l
                   , isoccs[ index].number
        );
}

static void iso3166_show_all( void)
{
 int i;

 iso3166_print_heading();

 i = 0;
 while( isoccs[ i].country[ 0] != ' ') {
        iso3166_print_cc( i);
        i++;
 }

 printf( "\nDomain      Explanation\n");
 printf( "%s\n", cc_hyp());

 i = 0;
 while( topdom[ i].str[ 0] != ' ') {
        printf( "%-12.12s%-60.60s\n", topdom[ i].str, topdom[ i].expl);
        i++;
 }

 printf( "\nSubdomain      Explanation\n");
 printf( "%s\n", cc_hyp());

 i = 0;
 while( subdom[ i].str[ 0] != ' ') {
        printf( "%-12.12s%-60.60s\n", subdom[ i].str, subdom[ i].expl);
        i++;
 }

 putchar( '\n');
 exit( 0);
}

static void iso3166_show_one( char *code)
{
 char buffer[ 256];
 unsigned short int number;
 int search_type = 0;
 int len         = 0;
 int i           = 0;
 int found       = 0;

 if( code == NULL)
     return;

 len = strlen( code);

 if( len > (sizeof( buffer) - 1)) {
     fprintf( stderr, "\n%s: %s Argument too long\n\n", progname, code);
     return;
 }

 strcpy( buffer, code);

 number = atoi( buffer);

 if( number > 0)
     search_type = ISO_SEARCH_NUMBER;
 else if( len == 2)
          search_type = ISO_SEARCH_2L;
      else if( len == 3)
               search_type = ISO_SEARCH_3L;
           else {
               cc_lowercase( buffer);
               search_type = ISO_SEARCH_COUNTRY;
           }

 while( isoccs[ i].country[ 0] != ' ') {
        switch( search_type) {
                case ISO_SEARCH_COUNTRY: buffer[ 0] = toupper( buffer[ 0]);
                                         if( strstr( isoccs[ i].country, buffer) != NULL) {
                                             iso3166_print_cc( i);
                                             found = 1;
                                         }
                                         break;
                case ISO_SEARCH_2L     : if( !strncasecmp( isoccs[ i].codes2l, buffer, 2)) {
                                             iso3166_print_cc( i);
                                             found = 1;
                                         }
                                         break;
                case ISO_SEARCH_3L     : if( !strncasecmp( isoccs[ i].codes3l, buffer, 3)) {
                                             iso3166_print_cc( i);
                                             found = 1;
                                         }
                                         break;
                case ISO_SEARCH_NUMBER : if( number == isoccs[ i].number) {
                                             iso3166_print_cc( i);
                                             found = 1;
                                         }
                                         break;
        }
        i++;
 }

 if( !found) {
     printf( "[%s] Not found ", code);
     if( index( code, '.') != NULL)
         printf( "(try -d %s)\n", code); 
     else
         printf( "\n"); 
 }

}

static void domain_name_print( char *str)
{
 char *dptr;
 char *wptr;
 char *buffer;
 int size;
 int i     = 0;
 int found = 0;
 int level = 0;
 int len   = 0;

 printf( "\nDomain name  : %s\n", str);

 size = strlen( str);

 buffer = ( char *) calloc( size + 2, sizeof( char));

 if( buffer == NULL) {
     fprintf( stderr, "\n%s: Not enough memory\n\n", progname);
     exit( 1);
 }

 buffer[ 0] = '.';
 strcat( buffer, str);

 dptr = rindex( buffer, '.');

 while( dptr != NULL) {
        found = 0;

        wptr = dptr + 1;

        len = strlen( wptr);

        if( level == 0) 
            printf( "Top domain   : %s \t" , wptr);
        else
            printf( "Sub domain #%d: %s \t", level, wptr);

        i = 0;
        while( !found && topdom[ i].str[ 0] != ' ') {
               if( len != strlen( topdom[ i].str)) {
                   i++;
                   continue;
               }
               if( !strncasecmp( topdom[ i].str, wptr, len)) {
                   printf( "(%s)", topdom[ i].expl);
                   found = 1;
               }
               i++;
        }

        i = 0;
        while( !found && subdom[ i].str[ 0] != ' ') {
               if( len != strlen( subdom[ i].str)) {
                   i++;
                   continue;
               }
               if( !strncasecmp( subdom[ i].str, wptr, len)) {
                   printf( "(%s)", subdom[ i].expl);
                   found = 1;
               }
               i++;
        }

        i = 0;

        if( level == 0)
            while( !found && isoccs[ i].country[ 0] != ' ') {
                   if( len != 2) {
                       i++;
                       continue;
                   }
                   if( !strncasecmp( isoccs[ i].codes2l, wptr, len)) {
                       printf( "(%s)", isoccs[ i].country);
                       found = 1;
                   }
                   i++;
            }

        if( !found)
            printf( "(Unknown)");

        putchar( '\n');

        level++;

        *dptr = 0;
        dptr = rindex( buffer, '.');
 } /* end while */

 putchar( '\n');

 free( buffer);
}

