/*
 * Copyright (c) 2017-2019 ARM Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "JSONPrinter.h"

#include "../Framework.h"
#include "../instruments/Measurement.h"

#include <algorithm>

namespace arm_compute
{
namespace test
{
namespace framework
{
void JSONPrinter::print_separator(bool &flag)
{
    if(flag)
    {
        flag = false;
    }
    else
    {
        *_stream << ",";
    }
}

template <typename T>
void JSONPrinter::print_strings(T &&first, T &&last)
{
    bool              first_entry = true;
    std::stringstream log;

    while(first != last)
    {
        print_separator(first_entry);

        *_stream << R"(")";

        log.str(*first);

        for(std::string line; !std::getline(log, line).fail();)
        {
            *_stream << line << "; ";
        }

        *_stream << R"(")";

        ++first;
    }
}

void JSONPrinter::print_entry(const std::string &name, const std::string &value)
{
    print_separator(_first_entry);

    *_stream << R"(")" << name << R"(" : ")" << value << R"(")";
}

void JSONPrinter::print_global_header()
{
    *_stream << "{";
}

void JSONPrinter::print_global_footer()
{
    *_stream << "}\n";
}

void JSONPrinter::print_run_header()
{
    print_separator(_first_entry);

    *_stream << R"("tests" : {)";
}

void JSONPrinter::print_run_footer()
{
    *_stream << "}";
}

void JSONPrinter::print_test_header(const TestInfo &info)
{
    print_separator(_first_test);

    _first_test_entry = true;
    *_stream << R"(")" << info.name << R"(" : {)";
}

void JSONPrinter::print_test_footer()
{
    *_stream << "}";
}

void JSONPrinter::print_list_tests(const std::vector<TestInfo> &infos)
{
    *_stream << R"(, "list_tests" : {)";
    bool first = true;
    for(auto const &info : infos)
    {
        if(!first)
        {
            *_stream << ",";
        }
        *_stream << R"(")" << info.id << R"(" : { "name": ")" << info.name << R"(", "mode": ")" << info.mode << R"(", "status" : ")" << info.status << R"(" })";
        first = false;
    }
    *_stream << "}";
}
void JSONPrinter::print_errors_header()
{
    _errors.clear();
    _expected_errors.clear();
    _infos.clear();
}

void JSONPrinter::print_errors_footer()
{
    print_separator(_first_test_entry);

    *_stream << R"("errors" : [)";
    print_strings(_errors.begin(), _errors.end());
    *_stream << "]";

    *_stream << R"(, "expected_errors" : [)";
    print_strings(_expected_errors.begin(), _expected_errors.end());
    *_stream << "]";

    *_stream << R"(, "infos" : [)";
    print_strings(_infos.begin(), _infos.end());
    *_stream << "]";
}

void JSONPrinter::print_error(const std::exception &error, bool expected)
{
    if(expected)
    {
        _expected_errors.emplace_back(error.what());
    }
    else
    {
        _errors.emplace_back(error.what());
    }
}

void JSONPrinter::print_info(const std::string &info)
{
    _infos.push_back(info);
}

void JSONPrinter::print_measurements(const Profiler::MeasurementsMap &measurements)
{
    print_separator(_first_test_entry);

    *_stream << R"("measurements" : {)";

    for(auto i_it = measurements.cbegin(), i_end = measurements.cend(); i_it != i_end;)
    {
        *_stream << R"(")" << i_it->first << R"(" : {)";

        auto measurement_to_string = [](const Measurement & measurement)
        {
            if(measurement.raw_data().size() == 1)
            {
                return measurement.raw_data().front();
            }
            else
            {
                std::stringstream str;
                str << R"([")";
                str << join(measurement.raw_data().begin(), measurement.raw_data().end(), R"(",")");
                str << R"("])";
                return str.str();
            }
        };
        *_stream << R"("raw" : [)" << join(i_it->second.begin(), i_it->second.end(), ",", measurement_to_string) << "],";
        *_stream << R"("unit" : ")" << i_it->second.begin()->unit() << R"(")";
        *_stream << "}";

        if(++i_it != i_end)
        {
            *_stream << ",";
        }
    }

    *_stream << "}";
}
} // namespace framework
} // namespace test
} // namespace arm_compute
