#ifdef USE_OUTPUT_RESULT_XML
/*
 * AXFScenarioTestInternal.cpp
 */

#include "AXFScenarioTestInternal.hpp"
#include "AXCUtils.hpp"

#include <fstream>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <stdio.h>

std::string scenarioTestLastFilename("");
const std::string AXFScenarioTestInternal::filenameIsp("ScenarioIsp");
const std::string AXFScenarioTestInternal::filenameAx("ScenarioAx");

static std::string __xmlline("");

//ログ出力から試験結果を取り出しテキスト出力
// type = 0 : Isp - Log
//      = 1 : Ax  - Log
//      = 2 : Ax  - Logtrans(isp)
void AXFScenarioTestInternal::putOutputXML(int type, std::string logmsg){
  // 出力ファイル名選択
  if(type == TYPE_ISP_LOG){
    scenarioTestLastFilename = filenameIsp;
  } else {
    scenarioTestLastFilename = filenameAx;
  }
  std::string filename = scenarioTestLastFilename + "_result.txt";
  // 前回分が退避されている場合は前回保留分＋logmsg
  if((__xmlline.length() > 0) && (type == TYPE_AX_LOGTRANS)){
    logmsg = __xmlline + logmsg;
  }
  // log中からCaseEnd文字列を検索
  unsigned int pos = 0;
  pos = logmsg.find("### Scenario CaseEnd ###");
  if(pos != std::string::npos){
    // CaseEnd文字列以降の文字列を":"区切りで分割
    std::string xmlmsg = logmsg.substr(pos);
    std::vector<std::string> res = AXCUtils::split(xmlmsg, ":");
    if(res.size() >= 5){
      //分割数が規定以上である場合にファイルへ出力する
      std::ofstream outf;
      outf.open(filename.c_str(), std::ios::app);
      if(outf != NULL){
        for(unsigned int i=0; i< res.size(); i++){
          outf << res[i];
          if((i+1) < res.size()){
            outf << ":";
          }
        }
        //outf << std::endl;
        outf.close();
        if(type == TYPE_AX_LOGTRANS){
          //一時退避データ初期化
          __xmlline = "";
        }
      }
    }else{
      if(type == TYPE_AX_LOGTRANS){
        //次回分ログに跨るため一時退避
        __xmlline = xmlmsg;
      }
    }
  }
}

void AXFScenarioTestInternal::makeResultXML(std::string filename){
  std::string infile  = filename + "_result.txt";
  std::string outfile = filename + "_result.xml";
  std::ifstream inf(infile.c_str());
  if(inf == NULL){
    return;
  }
  std::ofstream outf;
  outf.open(outfile.c_str(), std::ios::trunc);
  if(outf == NULL){
    return;
  }

  std::cout << ">>>" << filename <<std::endl;

  int lastTestNo = 0;
  int testCount = 0;        // 試験総数
  int errorsCount = 0;      // エラー数
  int failuresCount = 0;    // 失敗数
  double totalTime = 0;     // 総試験時間
  std::string classname = filename;
  std::string outputXmlStr("");
  std::string line("");
  while(std::getline(inf, line)){
    std::vector<std::string> res = AXCUtils::split(line, ":");
    if((res.size() >= 5) && (0 == res[0].compare("### Scenario CaseEnd ###"))){
      //テスト番号
      int testno;
      std::istringstream noStr(res[1]);
      noStr >> testno;
      if(testno != lastTestNo){
        lastTestNo = testno;
        //テスト名;
        std::string name = res[2];
        //テスト時間
        int msec = 0;
        std::istringstream msecStr(res[3]);
        msecStr >> msec;
        std::ostringstream timeStr;
        double ftime = ((double)msec / 1000); // msec->sec変換
        totalTime += ftime;
        timeStr << std::fixed << std::setprecision(3) << ftime;
        //テスト結果
        std::string result = res[4];
        //エラーメッセージ
        std::string msg = "";
        if(res.size() >= 6){
          msg = res[5];
        }

        //testcase１件分のXMLを構築
        outputXmlStr += "<testcase classname=\"" + classname;
        outputXmlStr += "\" name=\"" + name;
        outputXmlStr += "\" time=\"" + timeStr.str() + "\"";
        if(0 == result.compare("SUCCESS")){
          outputXmlStr += " />\n";
        }else if(0 == result.compare("SKIP")){
          outputXmlStr += ">\n";
          outputXmlStr += "<skipped/>\n";
          outputXmlStr += "</testcase>\n";
        }else if(0 == result.compare("FAILED")){
          outputXmlStr += ">\n";
          outputXmlStr += "<failure type=\"test failed\" message=\"test failed\">\n";
          outputXmlStr += msg + "\n";
          outputXmlStr += "</failure>\n";
          outputXmlStr += "</testcase>\n";
          failuresCount++;
        }else if(0 == result.compare("ERROR")){
          outputXmlStr += ">\n";
          outputXmlStr += "<error type=\"test failed\" message=\"test failed\">\n";
          outputXmlStr += msg + "\n";
          outputXmlStr += "</error>\n";
          outputXmlStr += "</testcase>\n";
          errorsCount++;
        }
        testCount++;
      }
    }
  }
  //testsuite XMLに必要な情報を整形する
  std::ostringstream testsCntStr;
  std::ostringstream errorsCntStr;
  std::ostringstream failuresCntStr;
  std::ostringstream totalTimeStr;
  testsCntStr << testCount;
  errorsCntStr << errorsCount;
  failuresCntStr << failuresCount;
  totalTimeStr << std::fixed << std::setprecision(3) << totalTime;
  //ヘッダ等を生成し、testcaseのXMLを加える
  outf << "<?xml version=\"1.0\" ?>" << std::endl;
  outf << "<testsuite name=\"" + classname;
  outf << "\" tests=\"" + testsCntStr.str(); 
  outf << "\" errors=\"" + errorsCntStr.str(); 
  outf << "\" failures=\"" + failuresCntStr.str(); 
  outf << "\" time=\"" + totalTimeStr.str(); 
  outf << "\">" << std::endl;
  outf << outputXmlStr;
  outf << "</testsuite>" << std::endl;
  inf.close();
  outf.close();
}
#endif /* USE_OUTPUT_RESULT_XML */

