/*

                                   _JNJ`                        
                               .JNMH`                           
                              JMMF`       `;.                   
                            .NMM)          `MN.                 
                            MMM)            (MML                
                           (MMM`             MMML               
                     M  I  D  N  I  G  H  T    C  o  D  E       
                           (NMMF             MHNH               
                            NMML            .MMM                
                             NMML          .NMH                 
                              4MMNL       .#F                   
                               `4HNNL_   `                      
                                   `"""`                        

                          Copyright (C) 2004-2006
       "Ian (Larry) Latter" <ian dot latter at midnightcode dot org>

    Midnight Code is a registered trademark of Ian Latter.

    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, and mirrored at the Midnight Code web
    site; as at version 2 of the License only.
  
    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
    (version 2) along with this program; if not, write to the Free
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA, or see http://midnightcode.org/gplv2.txt

*/

/* init.c :: Midnight Code library based system initialiser		*/


#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
// #include <arpa/inet.h>


#include <libmidnightcode.h>
#include "init.h"



int
main(int argc, char **argv) {
  int ret_i;
  int help = 0;
  void * tmp_void_p;
  struct midnightcode_config_head_t * config_list_head_p;
  struct midnightcode_config_head_t * out_config_list_head_p;
  struct midnightcode_config_element_t * now_element, *old_element;

  struct midnightcode_interface_head_t * config_interface_list_head_p;
  struct midnightcode_interface_head_t * interface_list_head_p;

  struct midnightcode_disk_head_t * config_disk_list_head_p;
  struct midnightcode_disk_head_t * disk_list_head_p;



  /* SWITCHES */
  struct entry_struct_name {
    int test_val;
    midnightcode_list_entry(entry_struct_name);
  };


  struct midnightcode_switch_t switches[] = {
    { "h", "help", "Display this help/usage screen",
      MIDNIGHTCODE_PARSE_TYPE_NONE, 0, 0, &help },
    { 0 }
  };



  /* DISK STUFF */

  midnightcode_list_init(disk_struct_head, midnightcode_disk_element_t);
  tmp_void_p = (void *)&disk_struct_head;
  disk_list_head_p = tmp_void_p;

  midnightcode_list_init(config_disk_struct_head, midnightcode_disk_element_t);
  tmp_void_p = (void *)&config_disk_struct_head;
  config_disk_list_head_p = tmp_void_p;



  /* INTERFACE STUFF */

  midnightcode_list_init(interface_struct_head,
                         midnightcode_interface_element_t);
  tmp_void_p = (void *)&interface_struct_head;
  interface_list_head_p = tmp_void_p;

  midnightcode_list_init(config_interface_struct_head,
                         midnightcode_interface_element_t);
  tmp_void_p = (void *)&config_interface_struct_head;
  config_interface_list_head_p = tmp_void_p;



  /* CONFIG FILE */

  midnightcode_list_init(config_struct_head, midnightcode_config_element_t);
  tmp_void_p = (void *)&config_struct_head;
  config_list_head_p = tmp_void_p;
  midnightcode_list_init(out_config_struct_head, midnightcode_config_element_t);
  tmp_void_p = (void *)&out_config_struct_head;
  out_config_list_head_p = tmp_void_p;

  old_element = malloc(sizeof(struct midnightcode_config_element_t));
  now_element = malloc(sizeof(struct midnightcode_config_element_t));







  midnightcode_logo(0, MIDNIGHTCODE_COLOUR_STYLE_BLOOD_MOON);

  if((ret_i = midnightcode_switch_process(argc, argv, switches)) != 0) {
    midnightcode_license(0, MIDNIGHTCODE_COLOUR_STYLE_BLOOD_MOON, 
      MIDNIGHTCODE_LICENSE_TEXT_COPYRIGHT);
    fprintf(stdout, "    Error in switches, switch \"%s\" is unkown at"
      " parameter number %d.\n\n", argv[ret_i], ret_i);
    midnightcode_switch_usage(MIDNIGHTCODE_SWITCH_STYLE_SOFT,
      argv[0], switches);
    fflush(stdout);
    exit(1);
  }
  if(help) {
    midnightcode_license(0, MIDNIGHTCODE_COLOUR_STYLE_BLOOD_MOON, 
      MIDNIGHTCODE_LICENSE_TEXT_COPYRIGHT);
    midnightcode_switch_usage(MIDNIGHTCODE_SWITCH_STYLE_SOFT,
      argv[0], switches);
    fflush(stdout);
    exit(1);
  }

  midnightcode_license(0, MIDNIGHTCODE_COLOUR_STYLE_BLOOD_MOON, 
    MIDNIGHTCODE_LICENSE_TEXT_ALL);
  fflush(stdout);



  /* NOTE: test sequence for init process */

      midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_H1,
        MIDNIGHTCODE_STATUS_STYLE_NORMAL,
        "Initialising %s", project);

      midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_H2,
        MIDNIGHTCODE_STATUS_STYLE_SOFT,
        "Retrieving system configuration;");
      midnightcode_init_config_load("int-in.cfg", config_list_head_p, 1);
      midnightcode_init_config_retrieve(config_disk_list_head_p,
        config_interface_list_head_p, NULL, NULL, NULL, config_list_head_p);

      midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_H2,
        MIDNIGHTCODE_STATUS_STYLE_SOFT,
        "Probing system hardware;");
      midnightcode_init_hardware(disk_list_head_p, interface_list_head_p);


      midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_TEXT,
        MIDNIGHTCODE_STATUS_STYLE_NORMAL,
        "Marry probed interfaces with configured interfaces");
      if((ret_i = midnightcode_interface_marry(interface_list_head_p,
        config_interface_list_head_p, MIDNIGHTCODE_INTERFACE_MARRY_DEFAULT))
        <= 0) {
        midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_FAIL);
      } else {
        midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_OKAY);
      }

      printf("    Debug: %d interfaces merged\n", ret_i);


  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_H2,
    MIDNIGHTCODE_STATUS_STYLE_SOFT,
    "Saving new configuration;");
  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_TEXT,
                           MIDNIGHTCODE_STATUS_STYLE_NORMAL,
                           "Restricting to eth interfaces");
  if((ret_i = midnightcode_interface_only(interface_list_head_p)) <= 0) {
    midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_FAIL);
  } else {
    midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_OKAY);
  }

  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_TEXT,
                           MIDNIGHTCODE_STATUS_STYLE_NORMAL,
                           "Adding interfaces to config");
  if((ret_i = midnightcode_interface_to_config(interface_list_head_p,
                           out_config_list_head_p)) != 0) {
    midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_FAIL);
  } else {
    midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_OKAY);
  }

  midnightcode_status_text(MIDNIGHTCODE_STATUS_TYPE_TEXT,
                           MIDNIGHTCODE_STATUS_STYLE_NORMAL,
                           "Config write to file");
  if((ret_i = midnightcode_config_write("int-out.cfg",
                           out_config_list_head_p,
                           MIDNIGHTCODE_CONFIG_TYPE_NEWSET, 0)) != 0) {
    midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_FAIL);
  } else {
    midnightcode_status_flag(MIDNIGHTCODE_STATUS_FLAG_OKAY);
  }


  return 0;
}



