/*
    Copyright 2005-2010 Intel Corporation.  All Rights Reserved.

    This file is part of Threading Building Blocks.

    Threading Building Blocks is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

    Threading Building Blocks 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
    along with Threading Building Blocks; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    As a special exception, you may use this file as part of a free software
    library without restriction.  Specifically, if other files instantiate
    templates or use macros or inline functions from this file, or you compile
    this file and link it with other files to produce an executable, this
    file does not by itself cause the resulting executable to be covered by
    the GNU General Public License.  This exception does not however
    invalidate any other reasons why the executable file might be covered by
    the GNU General Public License.
*/

#include "statistics.h"
#include "statistics_xml.h"

#define COUNT_PARAMETERS 3

#ifdef _MSC_VER
#define snprintf _snprintf
#endif

void GetTime(char* buff,int size_buff) 
{
    tm *newtime;
    time_t timer;
    time(&timer);
    newtime=localtime(&timer);
    strftime(buff,size_buff,"%H:%M:%S",newtime); 
}

void GetDate(char* buff,int size_buff) 
{
    tm *newtime;
    time_t timer;
    time(&timer);  
    newtime=localtime(&timer);
    strftime(buff,size_buff,"%Y-%m-%d",newtime); 
}


StatisticsCollector::TestCase StatisticsCollector::SetTestCase(const char *name, const char *mode, int threads)
{
    string KeyName(name);
    switch (SortMode)
    {
    case ByThreads: KeyName += Format("_%02d_%s", threads, mode); break;
    default:
    case ByAlg: KeyName += Format("_%s_%02d", mode, threads); break;
    }
    CurrentKey = Statistics[KeyName];
    if(!CurrentKey) {
        CurrentKey = new StatisticResults;
        CurrentKey->Mode = mode;
        CurrentKey->Name = name;
        CurrentKey->Threads = threads;
        CurrentKey->Results.reserve(RoundTitles.size());
        Statistics[KeyName] = CurrentKey;
    }
    return TestCase(CurrentKey);
}

StatisticsCollector::~StatisticsCollector()
{
    for(Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++)
        delete i->second;
}

void StatisticsCollector::ReserveRounds(size_t index)
{
    size_t i = RoundTitles.size();
    if (i > index) return;
    char buf[16];
    RoundTitles.resize(index+1);
    for(; i <= index; i++) {
        snprintf( buf, 15, "%u", unsigned(i+1) );
        RoundTitles[i] = buf;
    }
    for(Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++) {
        if(!i->second) printf("!!!'%s' = NULL\n", i->first.c_str());
        else i->second->Results.reserve(index+1);
    }
}

void StatisticsCollector::AddRoundResult(const TestCase &key, value_t v)
{
    ReserveRounds(key.access->Results.size());
    key.access->Results.push_back(v);
}

void StatisticsCollector::SetRoundTitle(size_t index, const char *fmt, ...)
{
    vargf2buff(buff, 128, fmt);
    ReserveRounds(index);
    RoundTitles[index] = buff;
}

void StatisticsCollector::AddStatisticValue(const TestCase &key, const char *type, const char *fmt, ...)
{
    vargf2buff(buff, 128, fmt);
    AnalysisTitles.insert(type);
    key.access->Analysis[type] = buff;
}

void StatisticsCollector::AddStatisticValue(const char *type, const char *fmt, ...)
{
    vargf2buff(buff, 128, fmt);
    AnalysisTitles.insert(type);
    CurrentKey->Analysis[type] = buff;
}

void StatisticsCollector::SetStatisticFormula(const char *name, const char *formula)
{
    Formulas[name] = formula;
}

void StatisticsCollector::SetTitle(const char *fmt, ...)
{
    vargf2buff(buff, 256, fmt);
    Title = buff;
}

string ExcelFormula(const string &fmt, size_t place, size_t rounds, bool is_horizontal)
{
    char buff[16];
    if(is_horizontal)
        snprintf(buff, 15, "RC[%u]:RC[%u]", unsigned(place), unsigned(place+rounds-1));
    else
        snprintf(buff, 15, "R[%u]C:R[%u]C", unsigned(place+1), unsigned(place+rounds));
    string result(fmt); size_t pos = 0;
    while ( (pos = result.find("ROUNDS", pos, 6)) != string::npos )
        result.replace(pos, 6, buff);
    return result;
}

void StatisticsCollector::Print(int dataOutput, const char *ModeName)
{
    FILE *OutputFile;
    if (dataOutput & StatisticsCollector::Stdout)
    {
        printf("\n-=# %s #=-\n", Title.c_str());
        if(SortMode == ByThreads)
            printf("    Name    |  #  | %s ", ModeName);
        else
            printf("    Name    | %s |  #  ", ModeName);
        for (AnalysisTitles_t::iterator i = AnalysisTitles.begin(); i != AnalysisTitles.end(); i++)
            printf("|%s", i->c_str()+1);

        for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++)
        {
            if(SortMode == ByThreads)
                printf("\n%12s|% 5d|%6s", i->second->Name.c_str(), i->second->Threads, i->second->Mode.c_str());
            else
                printf("\n%12s|%6s|% 5d", i->second->Name.c_str(), i->second->Mode.c_str(), i->second->Threads);
            Analysis_t &analisis = i->second->Analysis;
            AnalysisTitles_t::iterator t = AnalysisTitles.begin();
            for (Analysis_t::iterator a = analisis.begin(); a != analisis.end(); t++)
            {
                char fmt[8]; snprintf(fmt, 7, "|%% %us", unsigned(max(size_t(3), t->size())));
                if(*t != a->first)
                    printf(fmt, "");
                else {
                    printf(fmt, a->second.c_str()); a++;
                }
            }
        }
        printf("\n");
    }
    if (dataOutput & StatisticsCollector::HTMLFile)
    {
        if ((OutputFile = fopen((Name+".html").c_str(), "w+t")) != NULL)
        {
            char TimerBuff[100], DateBuff[100];
            GetTime(TimerBuff,sizeof(TimerBuff));
            GetDate(DateBuff,sizeof(DateBuff));
            fprintf(OutputFile, "<html><head>\n<title>%s</title>\n</head><body>\n", Title.c_str());
            //-----------------------
            fprintf(OutputFile, "<table id=\"h\" style=\"position:absolute;top:20\" border=1 cellspacing=0 cellpadding=2>\n");
            fprintf(OutputFile, "<tr><td><a name=hr href=#vr onclick=\"v.style.visibility='visible';"
                                "h.style.visibility='hidden';\">Flip[H]</a></td>"
                                "<td>%s</td><td>%s</td><td colspan=%u>%s</td>",
                DateBuff, TimerBuff, unsigned(AnalysisTitles.size() + RoundTitles.size()), Title.c_str());
            fprintf(OutputFile, "</tr>\n<tr bgcolor=#CCFFFF><td>Name</td><td>Threads</td><td>%s</td>", ModeName);
            for (AnalysisTitles_t::iterator i = AnalysisTitles.begin(); i != AnalysisTitles.end(); i++)
                fprintf(OutputFile, "<td>%s</td>", i->c_str()+1);
            for (size_t i = 0; i < RoundTitles.size(); i++)
                fprintf(OutputFile, "<td>%s</td>", RoundTitles[i].c_str());
            for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++)
            {
                fprintf(OutputFile, "</tr>\n<tr><td bgcolor=#CCFFCC>%s</td><td bgcolor=#CCFFCC>%d</td><td bgcolor=#CCFFCC>%4s</td>",
                    i->second->Name.c_str(), i->second->Threads, i->second->Mode.c_str());
                //statistics
                AnalysisTitles_t::iterator t = AnalysisTitles.begin();
                for (Analysis_t::iterator j = i->second->Analysis.begin(); j != i->second->Analysis.end(); t++)
                {
                    fprintf(OutputFile, "<td bgcolor=#FFFF99>%s</td>", (*t != j->first)?" ":(i->second->Analysis[j->first]).c_str());
                    if(*t == j->first) j++;
                }
                //data
                Results_t &r = i->second->Results;
                for (size_t k = 0; k < r.size(); k++)
                {
                    fprintf(OutputFile, "<td>");
                    fprintf(OutputFile, ResultsFmt, r[k]);
                    fprintf(OutputFile, "</td>");
                }
            }
            fprintf(OutputFile, "</tr>\n</table>\n");
            //////////////////////////////////////////////////////
            fprintf(OutputFile, "<table id=\"v\" style=\"visibility:hidden;position:absolute;top:20\" border=1 cellspacing=0 cellpadding=2>\n");
            fprintf(OutputFile, "<tr><td><a name=vr href=#hr onclick=\"h.style.visibility='visible';"
                                "v.style.visibility='hidden';\">Flip[V]</a></td>\n"
                                "<td>%s</td><td>%s</td><td colspan=%u>%s</td>", 
                DateBuff, TimerBuff, unsigned(max(Statistics.size()-2,size_t(1))), Title.c_str());

            fprintf(OutputFile, "</tr>\n<tr bgcolor=#CCFFCC><td bgcolor=#CCFFFF>Name</td>");
            for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++)
                fprintf(OutputFile, "<td>%s</td>", i->second->Name.c_str());
            fprintf(OutputFile, "</tr>\n<tr bgcolor=#CCFFCC><td bgcolor=#CCFFFF>Threads</td>");
            for (Statistics_t::iterator n = Statistics.begin(); n != Statistics.end(); n++)
                fprintf(OutputFile, "<td>%d</td>", n->second->Threads);
            fprintf(OutputFile, "</tr>\n<tr bgcolor=#CCFFCC><td bgcolor=#CCFFFF>%s</td>", ModeName);
            for (Statistics_t::iterator m = Statistics.begin(); m != Statistics.end(); m++)
                fprintf(OutputFile, "<td>%s</td>", m->second->Mode.c_str());

            for (AnalysisTitles_t::iterator t = AnalysisTitles.begin(); t != AnalysisTitles.end(); t++)
            {
                fprintf(OutputFile, "</tr>\n<tr bgcolor=#FFFF99><td bgcolor=#CCFFFF>%s</td>", t->c_str()+1);
                for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++)
                    fprintf(OutputFile, "<td>%s</td>", i->second->Analysis.count(*t)?i->second->Analysis[*t].c_str():" ");
            }

            for (size_t r = 0; r < RoundTitles.size(); r++)
            {
                fprintf(OutputFile, "</tr>\n<tr><td bgcolor=#CCFFFF>%s</td>", RoundTitles[r].c_str());
                for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++)
                {
                    Results_t &result = i->second->Results;
                    fprintf(OutputFile, "<td>");
                    if(result.size() > r)
                        fprintf(OutputFile, ResultsFmt, result[r]);
                    fprintf(OutputFile, "</td>");
                }
            }
            fprintf(OutputFile, "</tr>\n</table>\n</body></html>\n");
            fclose(OutputFile);
        }
    }
    if (dataOutput & StatisticsCollector::ExcelXML)
    {
        if ((OutputFile = fopen((Name+".xml").c_str(), "w+t")) == NULL) {
            printf("Can't open .xml file\n");
        } else {
            //vector<value_t> *TmpVect;
            //Statistics_t::iterator ii, i = Statistics.begin();
            //Analysis_t::iterator jj, j = i->second.Analysis.begin();
            char UserName[100];
            char SheetName[20];
            char TimerBuff[100], DateBuff[100];
#if _WIN32 || _WIN64
            strcpy(UserName,getenv("USERNAME"));
#else
            strcpy(UserName,getenv("USER"));
#endif
            //--------------------------------
            strcpy(SheetName,"Horizontal");
            GetTime(TimerBuff,sizeof(TimerBuff));
            GetDate(DateBuff,sizeof(DateBuff));
            //--------------------------
            fprintf(OutputFile, XMLHead, UserName, TimerBuff);
            fprintf(OutputFile, XMLStyles);
            fprintf(OutputFile, XMLBeginSheet, SheetName);
            fprintf(OutputFile, XMLNames,1,1,1,int(AnalysisTitles.size()+Formulas.size()+COUNT_PARAMETERS));
            fprintf(OutputFile, XMLBeginTable, int(RoundTitles.size()+Formulas.size()+AnalysisTitles.size()+COUNT_PARAMETERS+1/*title*/), int(Statistics.size()+1));
            fprintf(OutputFile, XMLBRow);
            fprintf(OutputFile, XMLCellTopName);
            fprintf(OutputFile, XMLCellTopThread);
            fprintf(OutputFile, XMLCellTopMode, ModeName);
            for (AnalysisTitles_t::iterator j = AnalysisTitles.begin(); j != AnalysisTitles.end(); j++)
                fprintf(OutputFile, XMLAnalysisTitle, j->c_str()+1);
            for (Formulas_t::iterator j = Formulas.begin(); j != Formulas.end(); j++)
                fprintf(OutputFile, XMLAnalysisTitle, j->first.c_str()+1);
            for (RoundTitles_t::iterator j = RoundTitles.begin(); j != RoundTitles.end(); j++)
                fprintf(OutputFile, XMLAnalysisTitle, j->c_str());
            fprintf(OutputFile, XMLCellEmptyWhite, Title.c_str());
            fprintf(OutputFile, XMLERow);
            //------------------------
            for (Statistics_t::iterator i = Statistics.begin(); i != Statistics.end(); i++)
            {
                fprintf(OutputFile, XMLBRow);
                fprintf(OutputFile, XMLCellName,  i->second->Name.c_str());
                fprintf(OutputFile, XMLCellThread,i->second->Threads);
                fprintf(OutputFile, XMLCellMode,  i->second->Mode.c_str());
                //statistics
                AnalysisTitles_t::iterator at = AnalysisTitles.begin();
                for (Analysis_t::iterator j = i->second->Analysis.begin(); j != i->second->Analysis.end(); at++)
                {
                    fprintf(OutputFile, XMLCellAnalysis, (*at != j->first)?"":(i->second->Analysis[j->first]).c_str());
                    if(*at == j->first) j++;
                }
                //formulas
                size_t place = 0;
                Results_t &v = i->second->Results;
                for (Formulas_t::iterator f = Formulas.begin(); f != Formulas.end(); f++, place++)
                    fprintf(OutputFile, XMLCellFormula, ExcelFormula(f->second, Formulas.size()-place, v.size(), true).c_str());
                //data
                for (size_t k = 0; k < v.size(); k++)
                {
                    fprintf(OutputFile, XMLCellData, v[k]);
                }
                if(v.size() < RoundTitles.size())
                    fprintf(OutputFile, XMLMergeRow, int(RoundTitles.size() - v.size()));
                fprintf(OutputFile, XMLERow);
            }
            //------------------------
            fprintf(OutputFile, XMLEndTable);
            fprintf(OutputFile, XMLWorkSheetProperties,1,1,3,3,int(RoundTitles.size()+AnalysisTitles.size()+Formulas.size()+COUNT_PARAMETERS));
            fprintf(OutputFile, XMLAutoFilter,1,1,1,int(AnalysisTitles.size()+Formulas.size()+COUNT_PARAMETERS));
            fprintf(OutputFile, XMLEndWorkSheet);
            //----------------------------------------
            fprintf(OutputFile, XMLEndWorkbook);
            fclose(OutputFile);
        }
    }
}
