#include "mapreduce_status_aggregator.h"

#include <library/cpp/testing/unittest/gtest.h>
#include <library/cpp/testing/unittest/registar.h>

#include <library/cpp/json/json_reader.h>
#include <library/cpp/json/json_value.h>

namespace {

const TStringBuf inputGood = R"json({
  "banfilter_trie_priemka": {
    "man1-0310.search.yandex.net:20810": {
      "status": {
        "SearchableTimestamp": 200
      }
    },
    "man1-0333.search.yandex.net:20810": {
      "status": {
        "SearchableTimestamp": 100,
        "Errors": [
          {"error": "Something wrong", "time_us": "1000"}
        ]
      }
    },
    "sas1-3259.search.yandex.net:31050": {
      "status": {
        "Errors": [
          {"error": "Error #5", "time_us": "1100"},
          {"error": "Error #4", "time_us": "900"},
          {"error": "Error #3", "time_us": "700"},
          {"error": "Error #2", "time_us": "600"},
          {"error": "Error #1", "time_us": "500"}
        ]
      }
    },
    "sas1-3704.search.yandex.net:31050": {
      "status": {
        "SearchableTimestamp": 180,
        "Errors": [
          {"error": "Something very wrong", "time_us": "750"}
        ]
      }
    }
  }
})json";

const TStringBuf outputGood = R"json({
  "stats": {
    "SearchableTimestamp": {
      "min": 0,
      "max": 200
    },
    "Errors": [
      {"error": "Error #5", "time_us": "1100"},
      {"error": "Something wrong", "time_us": "1000"},
      {"error": "Error #4", "time_us": "900"},
      {"error": "Something very wrong", "time_us": "750"},
      {"error": "Error #3", "time_us": "700"}
    ],
    "SkippedInstances": 0
  }
})json";

const TStringBuf inputWithSkipped = R"json({
  "banfilter_trie_priemka": {
    "man1-0310.search.yandex.net:20810": {
      "status": {
        "SearchableTimestamp": 200,
        "Errors": []
      }
    },
    "man1-0333.search.yandex.net:20810": {
      "status": {
        "SearchableTimestamp": 100,
        "Errors": [
          {"error": "Something wrong", "time_us": "1000"}
        ]
      }
    },
    "sas1-3259.search.yandex.net:31050": {},
    "sas1-3704.search.yandex.net:31050": {}
  }
})json";


const TStringBuf outputWithSkipped = R"json({
  "stats": {
    "SearchableTimestamp": {
      "min": 100,
      "max": 200
    },
    "Errors": [
      {"error": "Something wrong", "time_us": "1000"}
    ],
    "SkippedInstances": 2
  }
})json";

const TStringBuf inputAllSkipped = R"json({
  "banfilter_trie_priemka": {
    "man1-0310.search.yandex.net:20810": {},
    "man1-0333.search.yandex.net:20810": {},
    "sas1-3259.search.yandex.net:31050": {},
    "sas1-3704.search.yandex.net:31050": {}
  }
})json";

const TStringBuf outputAllSkipped = R"json({
  "stats": {
    "SearchableTimestamp": {
      "min": 0,
      "max": 0
    },
    "Errors": [],
    "SkippedInstances": 4
  }
})json";

void DoTest(TStringBuf inputJson, TStringBuf expectedOutputJson) {
    NJson::TJsonValue input, expectedOutput;
    NJson::ReadJsonFastTree(inputJson, &input, true);
    NJson::ReadJsonFastTree(expectedOutputJson, &expectedOutput, true);

    NJson::TJsonValue actualOutput(NJson::JSON_MAP);
    NRTYDeploy::AggregateMapReduceStatus(input, actualOutput, "banfilter_trie_priemka");

    ASSERT_EQ(expectedOutput, actualOutput);
}

TEST(DocfetcherScriptSuite, AggregateGood) {
    DoTest(inputGood, outputGood);
}

TEST(DocfetcherScriptSuite, AggregateWithSkipped) {
    DoTest(inputWithSkipped, outputWithSkipped);
}

TEST(DocfetcherScriptSuite, AggregateAllSkipped) {
    DoTest(inputAllSkipped, outputAllSkipped);
}

}

