/**
 * 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 <phosphor-logging/log.hpp>

namespace openpower
{
namespace pels
{
namespace src
{

using namespace phosphor::logging;

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:
                log<level::ERR>("Invalid Callout subsection type",
                                entry("CALLOUT_TYPE=0x%X", 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
