/*
 * Copyright (c) 2017-2019,2021 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_profiler_header(const std::string &header_data)
{
    if(header_data.size() > 0)
    {
        print_separator(_first_test_entry);
    }
    *_stream << header_data;
}

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
