#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstring>

#include "clean_bcc.h"

#define BCC_PATH "/home/mcoan/simple_os/bcc/bcc/bcc/bcc"

using namespace std;

class cc16 {
   const char * infile;
   const char * outfile;
   bool is_kernel;
   bool is_dot_s;

public:
   cc16(const char * in,
        const char * out,
        const bool is_kern,
        const bool dot_s) {
      infile = in;
      outfile = out;
      is_kernel = is_kern;
      is_dot_s = dot_s;
   }

   ~cc16() {

   }
 
   void run() {
      string cmd = string(BCC_PATH)
                   + string(" -0 -S ") 
                   + string(infile) 
                   + string(" -o /var/tmp/temp.s");
      system(cmd.c_str());

      ofstream out("/var/tmp/temp2.s");

      if(out) {
         out << "[BITS 16]" << endl;
         out << "[ORG 0]" << endl << endl;
         out << "[section text]" << endl << endl;


         if(is_kernel) {
            out << "\tmov\tax,cs" << endl;
            out << "\tmov\tds,ax" << endl;
            out << "\tmov\tes,ax" << endl;
            out << "\tmov\tax,0x7000" << endl;
            out << "\tmov\tss,ax" << endl;
            out << "\tmov\tsp,ss" << endl << endl << flush;

            out << "\tmov\tax,0x2000" << endl;
            out << "\tmov\tgs,ax" << endl;
            out << "\tmov\tbx,0" << endl << endl;

            out << "\tcall\t_main" << endl <<endl;
         }
         else {
            out << "\tmov\tax,cs" << endl;
            out << "\tmov\tds,ax" << endl;
            out << "\tmov\tes,ax" << endl << endl;

            out << "\tcall\t_main" << endl <<endl;

            out << "\tjmp\t0x1000:0" << endl << endl;
         }

         if(is_kernel) 
            out << "%include \"kern.asm\"" << endl << endl << flush;
         else 
            out << "%include \"io.asm\"" << endl << endl << flush;

         out << "[section text]" << endl;

         out.close();
      }

      //cmd = string("cat /var/tmp/temp.s | ./clean_bcc >> /var/tmp/temp2.s");
      //system(cmd.c_str());
      clean_bcc("/var/tmp/temp.s", "/var/tmp/temp2.s");

      if(is_dot_s) {
         cmd = string("cp /var/tmp/temp2.s ") + string(outfile);
      }
      else {
         cmd = string("nasm -f bin /var/tmp/temp2.s -o ") + string(outfile);
      }
      system(cmd.c_str());
   }
};

int
main(int argc,
     char ** argv,
     char ** envp)
{
   int rc = 0;

   const char * infile = NULL;
   const char * outfile = "a.out";
   bool kernel = false;
   bool dot_s = false;

   for(size_t i = 1; i < argc; i++) {
      if(strcmp(argv[i], "-o") == 0) {
         i++;
         outfile = argv[i];
cout << "outfile -> " << outfile << endl << flush;
      }
      else if(strcmp(argv[i], "-kernel") == 0) {
         kernel = true;
cout << "kernel -> true" << endl << flush;
      }
      else if(strcmp(argv[i], "-S") == 0) {
         dot_s =  true;
cout << "dot_s -> true" << endl << flush;
      }
      else {
         infile = argv[i];
cout << "infile -> " << infile << endl << flush;
      }
   }

   if(infile == NULL) {
      cerr << "usage: " << argv[0] << " <input>.c [-o <output>]" << endl;
      exit(1);
   }

   cc16 compiler(infile, outfile, kernel, dot_s);

   compiler.run();

   return rc;
}
