/**
 * Copyright © 2019 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 "callout.hpp"

#include "trace.hpp"

#include <fmt/format.h>

namespace openpower
{
namespace pels
{
namespace src
{

constexpr size_t locationCodeMaxSize = 80;

Callout::Callout(Stream& pel)
{
    pel >> _size >> _flags >> _priority >> _locationCodeSize;

    if (_locationCodeSize)
    {
        _locationCode.resize(_locationCodeSize);
        pel >> _locationCode;
    }

    size_t currentSize = 4 + _locationCodeSize;

    // Read in the substructures until the end of this structure.
    // Any stream overflows will throw an exception up to the SRC constructor
    while (_size > currentSize)
    {
        // Peek the type
        uint16_t type = 0;
        pel >> type;
        pel.offset(pel.offset() - 2);

        switch (type)
        {
            case FRUIdentity::substructureType:
            {
                _fruIdentity = std::make_unique<FRUIdentity>(pel);
                currentSize += _fruIdentity->flattenedSize();
                break;
            }
            case PCEIdentity::substructureType:
            {
                _pceIdentity = std::make_unique<PCEIdentity>(pel);
                currentSize += _pceIdentity->flattenedSize();
                break;
            }
            case MRU::substructureType:
            {
                _mru = std::make_unique<MRU>(pel);
                currentSize += _mru->flattenedSize();
                break;
            }
            default:
                trace::error(
                    fmt::format("Invalid Callout subsection type {}", type));
                throw std::runtime_error("Invalid Callout subsection type");
                break;
        }
    }
}

Callout::Callout(CalloutPriority priority, const std::string& locationCode,
                 const std::string& partNumber, const std::string& ccin,
                 const std::string& serialNumber) :
    Callout(priority, locationCode, partNumber, ccin, serialNumber,
            std::vector<MRU::MRUCallout>{})
{
}

Callout::Callout(CalloutPriority priority, const std::string& locationCode,
                 const std::string& partNumber, const std::string& ccin,
                 const std::string& serialNumber,
                 const std::vector<MRU::MRUCallout>& mrus)
{
    _flags = calloutType | fruIdentIncluded;

    _priority = static_cast<uint8_t>(priority);

    setLocationCode(locationCode);

    _fruIdentity =
        std::make_unique<FRUIdentity>(partNumber, ccin, serialNumber);

    if (!mrus.empty())
    {
        _flags |= mruIncluded;
        _mru = std::make_unique<MRU>(mrus);
    }

    _size = flattenedSize();
}

Callout::Callout(CalloutPriority priority, const std::string& procedure,
                 CalloutValueType type)
{
    _flags = calloutType | fruIdentIncluded;

    _priority = static_cast<uint8_t>(priority);

    _locationCodeSize = 0;

    _fruIdentity = std::make_unique<FRUIdentity>(procedure, type);

    _size = flattenedSize();
}

Callout::Callout(CalloutPriority priority, const std::string& symbolicFRU,
                 CalloutValueType type, const std::string& locationCode,
                 bool trustedLocationCode)
{
    _flags = calloutType | fruIdentIncluded;

    _priority = static_cast<uint8_t>(priority);

    setLocationCode(locationCode);

    _fruIdentity =
        std::make_unique<FRUIdentity>(symbolicFRU, type, trustedLocationCode);

    _size = flattenedSize();
}

void Callout::setLocationCode(const std::string& locationCode)
{
    if (locationCode.empty())
    {
        _locationCodeSize = 0;
        return;
    }

    std::copy(locationCode.begin(), locationCode.end(),
              std::back_inserter(_locationCode));

    if (_locationCode.size() < locationCodeMaxSize)
    {
        // Add a NULL, and then pad to a 4B boundary
        _locationCode.push_back('\0');

        while (_locationCode.size() % 4)
        {
            _locationCode.push_back('\0');
        }
    }
    else
    {
        // Too big - truncate it and ensure it ends in a NULL.
        _locationCode.resize(locationCodeMaxSize);
        _locationCode.back() = '\0';
    }

    _locationCodeSize = _locationCode.size();
}

size_t Callout::flattenedSize() const
{
    size_t size = sizeof(_size) + sizeof(_flags) + sizeof(_priority) +
                  sizeof(_locationCodeSize) + _locationCodeSize;

    size += _fruIdentity ? _fruIdentity->flattenedSize() : 0;
    size += _pceIdentity ? _pceIdentity->flattenedSize() : 0;
    size += _mru ? _mru->flattenedSize() : 0;

    return size;
}

void Callout::flatten(Stream& pel) const
{
    pel << _size << _flags << _priority << _locationCodeSize;

    if (_locationCodeSize)
    {
        pel << _locationCode;
    }

    if (_fruIdentity)
    {
        _fruIdentity->flatten(pel);
    }

    if (_pceIdentity)
    {
        _pceIdentity->flatten(pel);
    }
    if (_mru)
    {
        _mru->flatten(pel);
    }
}

} // namespace src
} // namespace pels
} // namespace openpower
