/**
 * 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 "record_manager.hpp"

#include <math.h>

#include <phosphor-logging/log.hpp>

#include <chrono>

namespace phosphor
{
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 (const 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;
}

} // namespace history
} // namespace power
} // namespace phosphor
