#include <errno.h>
#include <fstream>

#include <TRegexp.h>

#include "MArgs.h"

#include "MLog.h"
#include "MLogManip.h"

using namespace std;

static void Usage()
{
    gLog << endl;
    gLog << "Sorry the usage is:" << endl;
    gLog << "   showlog [options] filename" << endl;
    gLog << " or" << endl;
    gLog << "   showlog [options] < filename" << endl << endl;
    gLog.Usage();
    gLog << "   --version, -V             Show startup message with version number" << endl;
    gLog << "   -?, -h, --help            This help" << endl;
    gLog << endl;
    gLog << " This program converts colored output  made with ansi codes" << endl;
    gLog << " (like it is done by MLog)  and redirected into a file back" << endl;
    gLog << " into colored output." << endl << endl;
    gLog << " It cannot be used to get rid of the Ansi codes. To display" << endl;
    gLog << " colored output with less use the option -R, eg." << endl;
    gLog << "   less -R logfile.log" << endl << endl;
}

void RemoveAnsi(TString &s)
{
    static const TRegexp regexp("[][[][0-9]+[m]");

    while (1)
    {
        Ssiz_t len = 0;
        Ssiz_t idx = s.Index(regexp, &len);
        if (idx<0)
            break;

        s.Remove(idx, len);
    }
}

// FIXME: Enhance this tool with a converter to HTMl, etc.
//        Add option for 'no-colors'
int main(int argc, char **argv)
{
    MArgs arg(argc, argv);

    if (arg.HasOnly("-V") || arg.HasOnly("--version"))
        return 0;

    if (arg.HasOnly("-?") || arg.HasOnly("-h") || arg.HasOnly("--help"))
    {
        Usage();
        return 2;
    }

    const Bool_t kNoColors = arg.HasOnly("--no-colors") || arg.HasOnly("-a");

    gLog.Setup(arg);

    if (arg.GetNumOptions()>0)
    {
        gLog << warn << "WARNING - Unknown commandline options..." << endl;
        arg.Print("options");
        gLog << endl;
    }

    //
    // check for the right usage of the program
    //
    if (arg.GetNumArguments()>1)
    {
        Usage();
        return 2;
    }

    // casts necessary for gcc 2.95.3
    istream *in = arg.GetNumArguments()==1 ? (istream*)new ifstream(arg.GetArgumentStr(0)) : (istream*)&cin;
    if (!*in)
    {
        gLog << "Cannot open file " << arg.GetArgumentStr(0) << ": " << strerror(errno) << endl;
        return 2;
    }

    TString s;
    while (1)
    {
        s.ReadLine(*in);
        if (!*in)
            break;

        if (kNoColors)
            RemoveAnsi(s);
        else
            s.ReplaceAll("", "\033");
        gLog << s << endl;
    }

    if (in!=&cin)
        delete in;

    return 0;
}
