// *************************************************************
// File logging.C
// -------------------------------------------------------------
// Created: Ingmar Egger
//
// Tool fuer Instrumentierung
// *************************************************************

#include <stdio.h>
#include <stdlib.h>
#include <hyperg/utils/str.h>
#include <hyperg/utils/environ.h>
#include <hyperg/utils/hgunistd.h>
#include <hyperg/utils/filestat.h>
#include <IV-look/kit.h>
#include <InterViews/style.h>
#include <sys/types.h>
#include <time.h>
#include <InterViews/logging.h>

Instrumentation* Instrumentation::instance_ = nil;

Instrumentation::Instrumentation()
{
  Style* style = WidgetKit::instance()->style();
  instrumented = style->value_is_on("instrumented");
  RString home;
  Environ::getEnv("HOME", home); 
  RString fname12 = home + "/.harmony-log/.transmission-finished";
  FILE* trfile;

  trfile = fopen(fname12,"r");   //--- open infofile
  if (trfile) {
     fclose(trfile);
     instrumented = 0;     
  }       
}

void Instrumentation::init(unsigned char viewer, const char* sid)
{
  transok = false;
  transnok = false;
  first_time = false;
  last_time = false;
  if(!instrumented) return;
  FileStat fs;
  RString home;
  Environ::getEnv("HOME", home);
  path = home + "/.harmony-log";
  WidgetKit::instance()->style()->find_attribute("logpath", path);
  if (fs.load(path))
  {
    if (!fs.isDir())
    {
      instrumented = 0;
      cerr << "Logfile-Directory is not a directory" << endl;
      cerr << "No logfiles will be created" << endl;
    }
  }
  else
  {
    RString command6 = "mkdir " + path + "\n";
    if (system(command6.string()) != 0)
    {
      instrumented = 0;
      cerr << "Couldn't create Logfile-Directory - Error in mkdir-command" << endl;
      cerr << "No logfiles will be created" << endl;
    }
    first_time = true;
  }
  if (path[path.length()-1] != '/') path += "/";
  session_id = sid;
  path += session_id;
  if (!fs.load(path))
  {
    RString command6 = "mkdir " + path + "\n";
    if (system(command6.string()) != 0)
    {
      instrumented = 0;
      cerr << "Couldn't create Logfile-Directory - Error in mkdir-command" << endl;
      cerr << "No logfiles will be created" << endl;
    }
  }
  if (path[path.length()-1] != '/') path += "/";

  viewername = viewer;
  pid_t pid = getpid();
  char s[32];
  sprintf(s, "%ld", pid);
  switch(viewername)       //---- create logfilenames depending on viewertype
  {                        //---- e.g.: 1075.hartextd.123.log (session_number.viewer.process_id.log)
    case 8: {
              if (!first_time) {
                RString fname = path + "/../.start-time";
                time_t tp2;
                FILE* timefile;
                long timenow,time30;

                timenow = time(&tp2);         //--- get actual time
                timefile = fopen(fname,"r");   //--- open timefile
                if (timefile) {
                  fscanf(timefile,"%ld",&time30); //--- read previous stored time
                  fclose(timefile);
                  long period = 30;
                  WidgetKit::instance()->style()->find_attribute("testPeriod", period);
                  time30 += period * 86400;    //--- calculate stored time + 30 days (equ 2592000 secs)
                  if ( timenow > time30 ) {    //--- if 30 days have passed
                    last_time = true;
                    return;
                  }
                }
                else
                  first_time = true;
              }

              logfilename = path + session_id + ".harmony." + s + ".log";
              logfile = fopen(logfilename,"a");
              write_prefix(startviewer);
              write_to_log(startsession_harmony);
              break;
            }
    case 9: {
              logfilename = path + session_id + ".hartextd." + s + ".log";
              logfile = fopen(logfilename,"a");
              write_prefix(startviewer);
              write_to_log(startsession_hartextd);
              break;
            }
   case 10: {
              logfilename = path + session_id + ".harimaged." + s + ".log";
              logfile = fopen(logfilename,"a");
              write_prefix(startviewer);
              write_to_log(startsession_harimaged);
              break;
            }
   case 11: {
              logfilename = path + session_id + ".harfilmd." + s + ".log";
              logfile = fopen(logfilename,"a");
              write_prefix(startviewer);
              write_to_log(startsession_harfilmd);
              break;
            }
   case 12: {
              logfilename = path + session_id + ".harscened." + s + ".log";
              logfile = fopen(logfilename,"a");
              write_prefix(startviewer);
              write_to_log(startsession_harscened);
              break;
            }
   case 13: {
              RString fname19 = home + "/.harmony-log/.start-time";
              FILE* tr2file;
              tr2file = fopen(fname19,"r");   //--- open infofile
              if (!tr2file) {
                fclose(tr2file);
                instrumented = 0;     
              }       
              if (instrumented) { 
                logfilename = path + session_id + ".haradmin." + s + ".log";
                logfile = fopen(logfilename,"a");
                write_prefix(startviewer);
                write_to_log(startsession_haradmin);
              }
              break;
            }
   case 14: {
              logfilename = path + session_id + ".hareditAPITool." + s + ".log";
              logfile = fopen(logfilename,"a");
              write_prefix(startviewer);
              write_to_log(startsession_hareditapitool);
              break;
            }
  }
  write_prefix(log_init_value);
}

Instrumentation* Instrumentation::instance()
{
  if (!instance_)
    instance_ = new Instrumentation();

  return instance_;
}

Instrumentation::~Instrumentation()
{
  if(!instrumented) return;
  switch(viewername)   //---- close logfiles and backup them with gzip and finally create
  {                   //----  one tar-file when the current harmony-session is closed
    case 8: {
              write_prefix(endviewer);
              write_to_log(endsession_harmony);
              break;
            }
    case 9: {
              write_prefix(endviewer);
              write_to_log(endsession_hartextd);
              break;
            }
   case 10: {
              write_prefix(endviewer);
              write_to_log(endsession_harimaged);
              break;
            }
   case 11: {
              write_prefix(endviewer);
              write_to_log(endsession_harfilmd);
              break;
            }
   case 12: {
              write_prefix(endviewer);
              write_to_log(endsession_harscened);
              break;
            }
   case 13: {
              write_prefix(endviewer);
              write_to_log(endsession_haradmin);
              break;
            }
   case 14: {
              write_prefix(endviewer);
              write_to_log(endsession_hareditapitool);
              break;
            }
  }
  write_prefix(log_init_value);
  fclose(logfile);
  RString fullname;
  RString command = "gzip";                //--- if gzip exists ok,
  if (FileStat::which(command,fullname))   //--- else use compress
  {
    RString command1 = fullname + " " + logfilename + "\n";
    system(command1.string());
  }
  else
  {
    RString command1 = "compress " + logfilename + "\n";
    system(command1.string());
  }
}

void Instrumentation::write_prefix(unsigned char prefix_log)
{
  prefix = prefix_log;  //--- set a flag corresponding to the viewertype
}

void Instrumentation::write_to_log(const char* action)
{
  if (instrumented)   //--- write data in the logfile
  {
   time_t tp;
   RString s_prefix;
   RString result;
   RString tempt;

   time(&tp);
   tempt = ctime(&tp);
   switch(prefix)
   {
     case 0:
            {
              s_prefix = "startviewer ";
              break;
            }
     case 1:
            {
              s_prefix = "endviewer ";
              break;
            }
     case 2:
            {
              s_prefix = "menu ";
              break;
            }
     case 3:
            {
              s_prefix = "button ";
              break;
            }
     case 4:
            {
              s_prefix = "key ";
              break;
            }
     case 5:
            {
              s_prefix = "dclick ";
              break;
            }
     case 6:
            {
              s_prefix = "initvalue ";
              break;
            }
     case 7:
            {
              s_prefix = "errormessage ";
              break;
            }          
   }
   result = s_prefix;
   RString raction(action);
   if (prefix == 7) {
     raction.subst('\n', ' ');
     raction += " ";
   }
   result += raction;
   result += tempt;
   fprintf(logfile,"%s",result.string());
   write_prefix(log_init_value);
  }
}

void Instrumentation::start()
{
  RString fname = path + "/../.start-time";
  time_t tp1;
  FILE* timefile;
  long l1;

  l1 = time(&tp1);
  timefile = fopen(fname,"w");
  fprintf(timefile,"%ld",l1);
  fclose(timefile);
}

void Instrumentation::finish()
{
  //--- start tar + datatransmission-session ----
  RString home;
  Environ::getEnv("HOME", home);
  RString dummy_path = home + "/.harmony-log\n";
  RString har_home;
  Environ::getEnv("HARMONY_HOME", har_home);
  har_home += "/bin/";
  RString command7 = "prepare.pl " + dummy_path + " \n";
  if (system((har_home + command7).string()) != 0)
  {
    if (system(command7.string()) != 0)
    {
      instrumented = 0;
      return;
    }
  }
  RString command8 = "client.pl \n";
  if (system((har_home + command8).string()) != 0)
  {
    if (system(command8.string()) != 0)
    {
      instrumented = 0;
      return;
    }
   }
  long info;
  RString fname11 = home + "/.harmony-log/.transmission-info";
  FILE* infofile;

  infofile = fopen(fname11,"r");   //--- open infofile
  if (infofile) {
     fscanf(infofile,"%ld",&info); //--- read file
     fclose(infofile);
     remove(fname11);
  }        
  if (info == 999) { 
          transnok = false;
          transok = true;
  } 
  else  { 
          transnok = true; 
          transok = false;
  } 
  
  RString fname = home + "/.harmony-log/.start-time";
  time_t tp1;
  FILE* timefile;
  long l1;

  l1 = time(&tp1);
  l1 += 30000000;
  timefile = fopen(fname,"w");
  fprintf(timefile,"%ld",l1);
  fclose(timefile);

  instrumented = 0;

  RString fname13 = home + "/.harmony-log/.transmission-finished";

  FILE* tr1file;
  long l15;
  l15 = 6666;

  tr1file = fopen(fname13,"w");
  fprintf(tr1file,"%ld",l15);
  fclose(tr1file);
}
