/**
 * Copyright 2022 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "logging.hpp"

#include "../tuning.hpp"
#include "pid.hpp"

#include <chrono>
#include <fstream>
#include <iostream>
#include <map>
#include <string>

namespace pid_control
{
namespace ec
{

// Redundant log entries only once every 60 seconds
static constexpr int logThrottle = 60 * 1000;

static std::map<std::string, PidCoreLog> nameToLog;

static bool CharValid(const std::string::value_type& ch)
{
    // Intentionally avoiding invoking locale support here
    if ((ch >= 'A') && (ch <= 'Z'))
    {
        return true;
    }
    if ((ch >= 'a') && (ch <= 'z'))
    {
        return true;
    }
    if ((ch >= '0') && (ch <= '9'))
    {
        return true;
    }
    return false;
}

static std::string StrClean(const std::string& str)
{
    std::string res;
    size_t len = str.size();
    for (size_t i = 0; i < len; ++i)
    {
        const auto& c = str[i];
        if (!(CharValid(c)))
        {
            continue;
        }
        res += c;
    }
    return res;
}

static void DumpContextHeader(std::ofstream& file)
{
    file << "epoch_ms,input,setpoint,error";
    file << ",proportionalTerm";
    file << ",integralTerm1,integralTerm2";
    file << ",derivativeTerm";
    file << ",feedFwdTerm,output1,output2";
    file << ",minOut,maxOut";
    file << ",integralTerm3,output3";
    file << ",integralTerm,output";
    file << "\n" << std::flush;
}

static void DumpContextData(std::ofstream& file,
                            const std::chrono::milliseconds& msNow,
                            const PidCoreContext& pc)
{
    file << msNow.count();
    file << "," << pc.input << "," << pc.setpoint << "," << pc.error;
    file << "," << pc.proportionalTerm;
    file << "," << pc.integralTerm1 << "," << pc.integralTerm2;
    file << "," << pc.derivativeTerm;
    file << "," << pc.feedFwdTerm << "," << pc.output1 << "," << pc.output2;
    file << "," << pc.minOut << "," << pc.maxOut;
    file << "," << pc.integralTerm3 << "," << pc.output3;
    file << "," << pc.integralTerm << "," << pc.output;
    file << "\n" << std::flush;
}

static void DumpCoeffsHeader(std::ofstream& file)
{
    file << "epoch_ms,ts,integral,lastOutput";
    file << ",proportionalCoeff,integralCoeff";
    file << ",derivativeCoeff";
    file << ",feedFwdOffset,feedFwdGain";
    file << ",integralLimit.min,integralLimit.max";
    file << ",outLim.min,outLim.max";
    file << ",slewNeg,slewPos";
    file << ",positiveHysteresis,negativeHysteresis";
    file << "\n" << std::flush;
}

static void DumpCoeffsData(std::ofstream& file,
                           const std::chrono::milliseconds& msNow,
                           pid_info_t* pidinfoptr)
{
    // Save some typing
    const auto& p = *pidinfoptr;

    file << msNow.count();
    file << "," << p.ts << "," << p.integral << "," << p.lastOutput;
    file << "," << p.proportionalCoeff << "," << p.integralCoeff;
    file << "," << p.derivativeCoeff;
    file << "," << p.feedFwdOffset << "," << p.feedFwdGain;
    file << "," << p.integralLimit.min << "," << p.integralLimit.max;
    file << "," << p.outLim.min << "," << p.outLim.max;
    file << "," << p.slewNeg << "," << p.slewPos;
    file << "," << p.positiveHysteresis << "," << p.negativeHysteresis;
    file << "\n" << std::flush;
}

void LogInit(const std::string& name, pid_info_t* pidinfoptr)
{
    if (!coreLoggingEnabled)
    {
        // PID logging not enabled by configuration, silently do nothing
        return;
    }

    if (name.empty())
    {
        std::cerr << "PID logging disabled because PID does not have a name\n";
        return;
    }

    std::string cleanName = StrClean(name);
    if (cleanName.empty())
    {
        std::cerr << "PID logging disabled because PID name is unusable: "
                  << name << "\n";
        return;
    }

    auto iterExisting = nameToLog.find(name);

    if (iterExisting != nameToLog.end())
    {
        std::cerr << "PID logging reusing existing file: " << name << "\n";
    }
    else
    {
        // Multiple names could collide to the same clean name
        // Make sure clean name is not already used
        for (const auto& iter : nameToLog)
        {
            if (iter.second.nameClean == cleanName)
            {
                std::cerr << "PID logging disabled because of name collision: "
                          << name << "\n";
                return;
            }
        }

        std::string filec = loggingPath + "/pidcore." + cleanName;
        std::string filef = loggingPath + "/pidcoeffs." + cleanName;

        std::ofstream outc;
        std::ofstream outf;

        outc.open(filec);
        if (!(outc.good()))
        {
            std::cerr << "PID logging disabled because unable to open file: "
                      << filec << "\n";
            return;
        }

        outf.open(filef);
        if (!(outf.good()))
        {
            // Be sure to clean up all previous initialization
            outf.close();

            std::cerr << "PID logging disabled because unable to open file: "
                      << filef << "\n";
            return;
        }

        PidCoreLog newLog;

        // All good, commit to doing logging by moving into the map
        newLog.nameOriginal = name;
        newLog.nameClean = cleanName;
        newLog.fileContext = std::move(outc);
        newLog.fileCoeffs = std::move(outf);

        // The streams within this object are not copyable, must move them
        nameToLog[name] = std::move(newLog);

        // This must now succeed, as it must be in the map
        iterExisting = nameToLog.find(name);

        // Write headers only when creating files for the first time
        DumpContextHeader(iterExisting->second.fileContext);
        DumpCoeffsHeader(iterExisting->second.fileCoeffs);

        std::cerr << "PID logging initialized: " << name << "\n";
    }

    auto msNow = LogTimestamp();

    // Write the coefficients only once per PID loop initialization
    // If they change, caller will reinitialize the PID loops
    DumpCoeffsData(iterExisting->second.fileCoeffs, msNow, pidinfoptr);

    // Force the next logging line to be logged
    iterExisting->second.lastLog = iterExisting->second.lastLog.zero();
    iterExisting->second.lastContext = PidCoreContext();
}

PidCoreLog* LogPeek(const std::string& name)
{
    auto iter = nameToLog.find(name);
    if (iter != nameToLog.end())
    {
        return &(iter->second);
    }

    return nullptr;
}

void LogContext(PidCoreLog& pidLog, const std::chrono::milliseconds& msNow,
                const PidCoreContext& coreContext)
{
    bool shouldLog = false;

    if (pidLog.lastLog == pidLog.lastLog.zero())
    {
        // It is the first time
        shouldLog = true;
    }
    else
    {
        auto since = msNow - pidLog.lastLog;
        if (since.count() >= logThrottle)
        {
            // It has been long enough since the last time
            shouldLog = true;
        }
    }

    if (pidLog.lastContext != coreContext)
    {
        // The content is different
        shouldLog = true;
    }

    if (!shouldLog)
    {
        return;
    }

    pidLog.lastLog = msNow;
    pidLog.lastContext = coreContext;

    DumpContextData(pidLog.fileContext, msNow, coreContext);
}

std::chrono::milliseconds LogTimestamp(void)
{
    auto clockNow = std::chrono::high_resolution_clock::now();
    auto msNow = std::chrono::duration_cast<std::chrono::milliseconds>(
        clockNow.time_since_epoch());
    return msNow;
}

} // namespace ec
} // namespace pid_control
