//CYCLONE MATRIX HOST NODE APPLICATION
//Hermann L. Johnson, 2019
//Free for unmodified distribution and non-commercial use.


NOTE: THIS FILE IS A SHELL.  It will not compile.



/*
  1.    A graphical interface.  Small.

  2.    A place to enter an IP address for a client connection, with ports.
        The default is drawn from the default gateway.  Default upload
        port is 443 (text), download port is 80.

  3.    A Client Refresh Time field.  Default is 60 seconds.

  4.    A server ON/OFF switch, with ports. Default for transmitting is 80,
        for receipt is 443 (text).

  5.    This software operates upon the directory called CYCLONE.  If the
        directory does not exist, it creates it.  If the index.txt file does
        not exist, it builds it.  An indexdatetime.txt file is also made and
        utilized, with no regard for the file system's date stamping.  If
        the index.txt exists, but not the indexdatetime.txt, then that file is
        created with the timestamp of its creation.

  6.    There is a MUTEX/SEMAPHORE for each datafile.  Incoming data
        may need to be held in a buffer.  The server mode will take multiple
        connections.  The default is 10.  This can be overriden as a command
        line parameter.

  *The editable config file will preserve the other settings and permit
   more advanced configuration.


DATAFILE LOCKING:
 Multiple instances of this software should rely upon the OS to lock
 files.  Attempts to access a locked file should result in responsible
 waiting.  A single instance of the software should properly manage its
 own file access and not rely upon the operating system for internal
 file management.

--------------------------------------------------------------------------

  THUS the Client Mode issues requests and takes data on a port (such as 80)
       and it uploads its data on another port (such as 443).
  AND  the Server Mode services requests on a port (such as 80)
       and it takes new data on another port (such as 443).

--------------------------------------------------------------------------

The config file overrides all defaults, but its parameters are overridden
by the commandline parameters.











Need a command line parameter for the limiting of message sizes

















Commandline parameters:

 -?

     Display this help and exit.


 -mode=[gui,secondary,secondarysingle[c,s]]

     gui                :  GUI.
     secondary            : commandline mode that utilizes TCP ports.
     secondarysingle[c,s] : same as secondary, but runs either as [c]lient
                            or as [s]erver and quits after one connection

 -shasum_executable=path_of_sha1sum     :Default is sha1sum.  If a path is
                                         used, it must be absolute.

 -macfinder_executable=path_of_mac_addr_finder :Which converts an IP to
                                                mac address.  Default is
                                                mactranslator
                                                If a path is used, it must be
                                                absolute.

 -defaultgw_executable=path_of_def_gw_finder   :Which provides the default
                                                gateway.  If a path is used,
                                                it must be absolute.

 -client_default_ip=destination     :destination is an IP address that the
                                     client will connect to

 -client_refresh_time=seconds       :time between client refreshes,
                                          default 300

 -client_max_pull=number            :max number of entries to pull during
                                     one connection

 -client_upload_ports=[number1,number2,...] :TCP ports to submit data,
                                             default 443.  The first one
                                             is for TXT.  The second does ZIP
                                             data, the third, TXT, etc,
                                             alternating.

 -client_download_port=number       :TCP port for request service, default 80


 -server_upload_ports=[number1,number2,...] :TCP port(s) to accept data,
                                               default 443.  The first one
                                               expects TXT.  The second
                                               port expects ZIP data, the
                                               third TXT, etc, alternating.

 -server_download_ports=[number1,number2,...]  :TCP port(s) to service
                                                  requests, default 80

 -server_max_connections=number      :default is 10


 -location_whitelist=[abbrevLocA,abbrevLocB...]  :Strict localization will
                                                  reduce data quantities.
                                                  Whitelists blacklist all
                                                  that are unspecified.

 -location_blacklist=[abbrevLocA,abbrevLocB...]  :Blacklist for abbreviated
                                                  location.

 -root_directory=path        :default is CYCLONE
                              To make it absolute, provide prefix.

 -config=path_to_config_file           :default is -root_directory/.config
                                        The config file stores all settings.
                                        The JAR will contain a config file
                                        that will be used for additional
                                        defaults if there is no specified
                                        config. Customized platform packages
                                        will contain differing configs.
                                        A leading prefix is necessary to make
                                        it absolute.  Specifying this will
                                        ignore -root_directory.

 -log=[hash,datetimestamp,hostip,hostmac]

      :A logfile is to be appended at $home/cyclone.log with the
       requested parameters.  NOTE: This does not identify the true origin
       of a message, its intent is to serve for analysis to identify spammy
       nodes.  Default is no logging.


 -mac_in_blacklist=[macA,macB,...]   :Blacklist for incoming data


 -mac_out_blacklist=[macA,macB,...]  :Blacklist for outgoing data

 -mac_in_whitelist=[macA,macB,...]   :Whitelist for incoming data
                                      blacklists all that are unspecified

 -mac_out_whitelist=[macA,macB,...]  :Whitelist for outgoing data
                                      blacklists all that are unspecified

 -days_old_limit=number              :Setting this to 1 means only datafiles
                                      with today's date will be utilized.
                                      This will strongly limit data quantities.

 -import_datafile=filename           :Import a location datafile.

*/




   public static void main(String argv[]) {

       Parameters parameters = new Parameters();
       parameters.take(argv);

       Main main = new Main(parameters);

   }

   public Main(Parameters parameters) {

       if(parameters.get_HELP()) { displayHelp(); System.exit(0); }

       parameters.readConfigFile();

       parameters.outputParametersToStream(System.err);

       dataManager = new DataManager(parameters.get_ROOT_DIRECTORY());

//if !startUp..
startUp(parameters);


boolean running = true;

   }

   private void displayHelp() {

       try {
           File helpFile = new File("help.txt");
           BufferedReader reader = new BufferedReader(
                                         new FileReader(helpFile));
           while(reader.ready()) {
               System.err.println(reader.readLine());
           }
       } catch(Exception e) {
           System.err.println("Help file error!  Is it missing?");
       }

   }

   private boolean openServerRegular(Parameters parameters) {

       sct = new ServerConnectionThread(
               parameters.get_SERVER_UPLOAD_PORTS()[0], parameters.
               get_SERVER_MAX_CONNECTIONS(), dataManager, true, false);

       try {
           sct.start();
       } catch(Exception e) {
   System.err.println("Problem running server txt upload thread.");
          return false;
       }
       return true;

   }

   private boolean openServerZip(Parameters parameters) {

       sctZip = new ServerConnectionThread(
               parameters.get_SERVER_UPLOAD_PORTS()[1], parameters.
               get_SERVER_MAX_CONNECTIONS(), dataManager, true, true);

       try {
           sctZip.start();
       } catch(Exception e) {
   System.err.println("Problem running server zip upload thread.");
          return false;
       }
       return true;

   }

   private boolean openServerDownload(Parameters parameters) {

       sctDown = new ServerConnectionThread(
               parameters.get_SERVER_DOWNLOAD_PORTS()[0], parameters.
               get_SERVER_MAX_CONNECTIONS(), dataManager, false, true);

       try {
           sctDown.start();
       } catch(Exception e) {
   System.err.println("Problem running server download thread.");
          return false;
       }
       return true;

   }

   private boolean openClient(Parameters parameters) {

       ct = new ClientThread("127.0.0.1",
               parameters.get_CLIENT_DOWNLOAD_PORT(),parameters.
               get_CLIENT_UPLOAD_PORTS(),dataManager);
       try {
           ct.start();
       } catch(Exception e) {
   System.err.println("Problem running client thread. Exiting.");
          return false;
       }
       return true;

   }

   private boolean startUp(Parameters parameters) {

       openServerRegular(parameters);
       openServerZip(parameters);
       openServerDownload(parameters);
       openClient(parameters);

return true;
//What to return in case of failures?







//All datafile data is by stream.  It can be way too long for Strings.

//NOTE: DOWNLOAD FIRST AND UPLOAD, THEN CATALOGUE.

//NOTE: incoming entries are to be checked for number of fields.  If fully
//tokenized, strip the hash and leading token.  One way to know is by whether
//or not there are CAPS where abbreviated location should be.
//If (full-1) entries, with no
//leading token, it was properly set up.  If the number of tokens is less
//than that, it was badly set up, a new hash is made regardless of there
//being one or not, the fields are set by the server, with all dodgy
//fields combined to the main text field.

//NOTE: The client can store operating information in whatever files it
//wants, any sort of data can be put in the config file or any other files
//chosen by the client designer.

//NOTE: A broken connection (no trailing %LBK% has its data discarded)

//NOTE: A datafile cannot be trashed in the case of system shutdown or failure.
//one idea is to have the datafiles actually stored linearly, with an index
//that tells what position the entry is supposed to be in.  Let's say, two
//numbers, one showing the index of the one before it, and the other showing
//the index of what is behind it.  An output_datafile option or script
//will be needed to generate a datafile that is properly ordered.  Occasional
//reordering can be performed.  But if a datafile is worked on, the work must
//go to a temp file, and then the original file moved elsewhere, then the
//temp file moved to where the original file goes, then the original file
//removed..

// Client mode tries, by default, to connect to the computer's default
// gateway.  This is because the Cyclone Matrix wifi "server" it is
// connecting to will generally be configured to act as a DHCP server.

/* SYSTEM SPECIFIC DEFAULT GATEWAY(S) DETECTION CODE */
/*                                                   */
/*     ..LINUX..                                     */


// Uploading data to a HTTPS socket will result in a disconnect after
// one line.