/**
 * Copyright © 2017 IBM Corporation
 *
 * 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 <chrono>
#include <math.h>
#include <phosphor-logging/log.hpp>
#include "record_manager.hpp"

namespace witherspoon
{
namespace power
{
namespace history
{

using namespace phosphor::logging;

bool RecordManager::add(const std::vector<uint8_t>& rawRecord)
{
    if (rawRecord.size() == 0)
    {
        //The PS has no data - either the power supply just started up,
        //or it just got a SYNC.  Clear the history.
        records.clear();
        return true;
    }

    try
    {
        //Peek at the ID to see if more processing is needed.
        auto id = getRawRecordID(rawRecord);

        if (!records.empty())
        {
            auto previousID = std::get<recIDPos>(records.front());

            //Already have this record.  Done.
            if (previousID == id)
            {
                return false;
            }

            //Check that the sequence ID is in order.
            //If not, clear out current list.
            if ((previousID + 1) != id)
            {
                //If it just rolled over from 0xFF to 0x00, then no
                //need to clear.  If we see a 0 seemingly out of nowhere,
                //then it was a sync so clear the old records.
                auto rolledOver =
                    (previousID == lastSequenceID) &&
                    (id == FIRST_SEQUENCE_ID);

                if (!rolledOver)
                {
                    if (id != FIRST_SEQUENCE_ID)
                    {
                        log<level::INFO>(
                                "Noncontiguous INPUT_HISTORY sequence ID "
                                "found. Clearing old entries",
                                entry("OLD_ID=%ld", previousID),
                                entry("NEW_ID=%ld", id));
                    }
                    records.clear();
                }
            }
        }

        records.push_front(std::move(createRecord(rawRecord)));

        //If no more should be stored, prune the oldest
        if (records.size() > maxRecords)
        {
            records.pop_back();
        }
    }
    catch (InvalidRecordException& e)
    {
        return false;
    }

    return true;
}

auto RecordManager::getAverageRecords() -> DBusRecordList
{
    DBusRecordList list;

    for (const auto& r : records)
    {
        list.emplace_back(std::get<recTimePos>(r),
                          std::get<recAvgPos>(r));
    }

    return list;
}

auto RecordManager::getMaximumRecords() -> DBusRecordList
{
    DBusRecordList list;

    for (const auto& r : records)
    {
        list.emplace_back(std::get<recTimePos>(r),
                          std::get<recMaxPos>(r));
    }

    return list;
}

size_t RecordManager::getRawRecordID(
        const std::vector<uint8_t>& data) const
{
    if (data.size() != RAW_RECORD_SIZE)
    {
        log<level::ERR>("Invalid INPUT_HISTORY size",
                entry("SIZE=%d", data.size()));
        throw InvalidRecordException{};
    }

    return data[RAW_RECORD_ID_OFFSET];
}

Record RecordManager::createRecord(const std::vector<uint8_t>& data)
{
    //The raw record format is:
    //  0xAABBCCDDEE
    //
    //  where:
    //    0xAA = sequence ID
    //    0xBBCC = average power in linear format (0xCC = MSB)
    //    0xDDEE = maximum power in linear format (0xEE = MSB)
    auto id = getRawRecordID(data);

    auto time = std::chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now().time_since_epoch()).count();

    auto val = static_cast<uint16_t>(data[2]) << 8 | data[1];
    auto averagePower = linearToInteger(val);

    val = static_cast<uint16_t>(data[4]) << 8 | data[3];
    auto maxPower = linearToInteger(val);

    return Record{id, time, averagePower, maxPower};
}

int64_t RecordManager::linearToInteger(uint16_t data)
{
    //The exponent is the first 5 bits, followed by 11 bits of mantissa.
    int8_t exponent = (data & 0xF800) >> 11;
    int16_t mantissa = (data & 0x07FF);

    //If exponent's MSB on, then it's negative.
    //Convert from two's complement.
    if (exponent & 0x10)
    {
        exponent = (~exponent) & 0x1F;
        exponent = (exponent + 1) * -1;
    }

    //If mantissa's MSB on, then it's negative.
    //Convert from two's complement.
    if (mantissa & 0x400)
    {
        mantissa = (~mantissa) & 0x07FF;
        mantissa = (mantissa + 1) * -1;
    }

    auto value = static_cast<float>(mantissa) * pow(2, exponent);
    return value;
}

}
}
}
