//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include "QuantizationDataSet.hpp"
#include "CsvReader.hpp"

#define BOOST_FILESYSTEM_NO_DEPRECATED

#include <armnn/utility/IgnoreUnused.hpp>

#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>

namespace armnnQuantizer
{

QuantizationDataSet::QuantizationDataSet()
{
}

QuantizationDataSet::QuantizationDataSet(const std::string csvFilePath):
    m_QuantizationInputs(),
    m_CsvFilePath(csvFilePath)
{
    ParseCsvFile();
}

void AddInputData(unsigned int passId,
                  armnn::LayerBindingId bindingId,
                  const std::string& inputFilePath,
                  std::map<unsigned int, QuantizationInput>& passIdToQuantizationInput)
{
    auto iterator = passIdToQuantizationInput.find(passId);
    if (iterator == passIdToQuantizationInput.end())
    {
        QuantizationInput input(passId, bindingId, inputFilePath);
        passIdToQuantizationInput.emplace(passId, input);
    }
    else
    {
        auto existingQuantizationInput = iterator->second;
        existingQuantizationInput.AddEntry(bindingId, inputFilePath);
    }
}

QuantizationDataSet::~QuantizationDataSet()
{
}

void InputLayerVisitor::VisitInputLayer(const armnn::IConnectableLayer* layer,
                                        armnn::LayerBindingId id,
                                        const char* name)
{
    armnn::IgnoreUnused(name);
    m_TensorInfos.emplace(id, layer->GetOutputSlot(0).GetTensorInfo());
}

armnn::TensorInfo InputLayerVisitor::GetTensorInfo(armnn::LayerBindingId layerBindingId)
{
    auto iterator = m_TensorInfos.find(layerBindingId);
    if (iterator != m_TensorInfos.end())
    {
        return m_TensorInfos.at(layerBindingId);
    }
    else
    {
        throw armnn::Exception("Could not retrieve tensor info for binding ID " + std::to_string(layerBindingId));
    }
}


unsigned int GetPassIdFromCsvRow(std::vector<armnnUtils::CsvRow> csvRows, unsigned int rowIndex)
{
    unsigned int passId;
    try
    {
        passId = static_cast<unsigned int>(std::stoi(csvRows[rowIndex].values[0]));
    }
    catch (const std::invalid_argument&)
    {
        throw armnn::ParseException("Pass ID [" + csvRows[rowIndex].values[0] + "]" +
                                    " is not correct format on CSV row " + std::to_string(rowIndex));
    }
    return passId;
}

armnn::LayerBindingId GetBindingIdFromCsvRow(std::vector<armnnUtils::CsvRow> csvRows, unsigned int rowIndex)
{
    armnn::LayerBindingId bindingId;
    try
    {
        bindingId = std::stoi(csvRows[rowIndex].values[1]);
    }
    catch (const std::invalid_argument&)
    {
        throw armnn::ParseException("Binding ID [" + csvRows[rowIndex].values[0] + "]" +
                                    " is not correct format on CSV row " + std::to_string(rowIndex));
    }
    return bindingId;
}

std::string GetFileNameFromCsvRow(std::vector<armnnUtils::CsvRow> csvRows, unsigned int rowIndex)
{
    std::string fileName = csvRows[rowIndex].values[2];

    if (!boost::filesystem::exists(fileName))
    {
        throw armnn::ParseException("File [ " + fileName + "] provided on CSV row " + std::to_string(rowIndex) +
                                    " does not exist.");
    }

    if (fileName.empty())
    {
        throw armnn::ParseException("Filename cannot be empty on CSV row " + std::to_string(rowIndex));
    }
    return fileName;
}


void QuantizationDataSet::ParseCsvFile()
{
    std::map<unsigned int, QuantizationInput> passIdToQuantizationInput;
    armnnUtils::CsvReader reader;

    if (m_CsvFilePath == "")
    {
        throw armnn::Exception("CSV file not specified.");
    }

    // Parse CSV file and extract data
    std::vector<armnnUtils::CsvRow> csvRows = reader.ParseFile(m_CsvFilePath);
    if (csvRows.empty())
    {
        throw armnn::Exception("CSV file [" + m_CsvFilePath + "] is empty.");
    }

    for (unsigned int i = 0; i < csvRows.size(); ++i)
    {
        if (csvRows[i].values.size() != 3)
        {
            throw armnn::Exception("CSV file [" + m_CsvFilePath + "] does not have correct number of entries " +
                                   "on line " + std::to_string(i) + ". Expected 3 entries " +
                                   "but was " + std::to_string(csvRows[i].values.size()));
        }

        unsigned int passId = GetPassIdFromCsvRow(csvRows, i);
        armnn::LayerBindingId bindingId = GetBindingIdFromCsvRow(csvRows, i);
        std::string rawFileName = GetFileNameFromCsvRow(csvRows, i);

        AddInputData(passId, bindingId, rawFileName, passIdToQuantizationInput);
    }

    if (passIdToQuantizationInput.empty())
    {
        throw armnn::Exception("Could not parse CSV file.");
    }

    // Once all entries in CSV file are parsed successfully and QuantizationInput map is populated, populate
    // QuantizationInputs iterator for easier access and clear the map
    for (auto itr = passIdToQuantizationInput.begin(); itr != passIdToQuantizationInput.end(); ++itr)
    {
        m_QuantizationInputs.emplace_back(itr->second);
    }
}

}
