/**
 * Copyright © 2018 Intel 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.
 */
#pragma once

#include <boost/asio/spawn.hpp>
#include <ipmid/api-types.hpp>
#include <ipmid/message/types.hpp>
#include <ipmid/types.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/asio/connection.hpp>

#include <algorithm>
#include <cstdint>
#include <exception>
#include <memory>
#include <tuple>
#include <utility>
#include <vector>

namespace ipmi
{

struct Context
{
    using ptr = std::shared_ptr<Context>;

    Context() = delete;
    Context(const Context&) = default;
    Context& operator=(const Context&) = default;
    Context(Context&&) = delete;
    Context& operator=(Context&&) = delete;

    Context(std::shared_ptr<sdbusplus::asio::connection> bus, NetFn netFn,
            uint8_t lun, Cmd cmd, int channel, int userId, uint32_t sessionId,
            Privilege priv, int rqSA, int hostIdx,
            boost::asio::yield_context& yield) :
        bus(bus), netFn(netFn), lun(lun), cmd(cmd), channel(channel),
        userId(userId), sessionId(sessionId), priv(priv), rqSA(rqSA),
        hostIdx(hostIdx), yield(yield)
    {}

    std::shared_ptr<sdbusplus::asio::connection> bus;
    // normal IPMI context (what call is this, from whence it came...)
    NetFn netFn;
    uint8_t lun;
    Cmd cmd;
    int channel;
    int userId;
    uint32_t sessionId;
    Privilege priv;
    // srcAddr is only set on IPMB requests because
    // Platform Event Message needs it to determine the incoming format
    int rqSA;
    int hostIdx;
    boost::asio::yield_context yield;
};

namespace message
{

namespace details
{

template <typename A>
struct UnpackSingle;

template <typename T>
using UnpackSingle_t = UnpackSingle<utility::TypeIdDowncast_t<T>>;

template <typename A>
struct PackSingle;

template <typename T>
using PackSingle_t = PackSingle<utility::TypeIdDowncast_t<T>>;

// size to hold 64 bits plus one (possibly-)partial byte
static constexpr size_t bitStreamSize = ((sizeof(uint64_t) + 1) * CHAR_BIT);

} // namespace details

/**
 * @brief a payload class that provides a mechanism to pack and unpack data
 *
 * When a new request is being executed, the Payload class is responsible for
 * attempting to unpack all the required arguments from the incoming blob. For
 * variable-length functions, it is possible to have function signature have a
 * Payload object, which will then allow the remaining data to be extracted as
 * needed.
 *
 * When creating a response, the parameters returned from the callback use a
 * newly created payload object to pack all the parameters into a buffer that is
 * then returned to the requester.
 *
 * These interfaces make calls into the message/pack.hpp and message/unpack.hpp
 * functions.
 */
struct Payload
{
    Payload() = default;
    Payload(const Payload&) = default;
    Payload& operator=(const Payload&) = default;
    Payload(Payload&&) = default;
    Payload& operator=(Payload&&) = default;

    explicit Payload(SecureBuffer&& data) : raw(std::move(data)) {}

    ~Payload()
    {
        if (raw.size() != 0 && std::uncaught_exceptions() == 0 && !trailingOk &&
            !unpackCheck && !unpackError)
        {
            lg2::error(
                "Failed to check request for full unpack: raw size: {RAW_SIZE}",
                "RAW_SIZE", raw.size());
        }
    }

    /******************************************************************
     * raw vector access
     *****************************************************************/
    /**
     * @brief return the size of the underlying raw buffer
     */
    size_t size() const
    {
        return raw.size();
    }
    /**
     * @brief resize the underlying raw buffer to a new size
     *
     * @param sz - new size for the buffer
     */
    void resize(size_t sz)
    {
        raw.resize(sz);
    }
    /**
     * @brief return a pointer to the underlying raw buffer
     */
    uint8_t* data()
    {
        return raw.data();
    }
    /**
     * @brief return a const pointer to the underlying raw buffer
     */
    const uint8_t* data() const
    {
        return raw.data();
    }

    /******************************************************************
     * Response operations
     *****************************************************************/
    /**
     * @brief append a series of bytes to the buffer
     *
     * @tparam T - the type pointer to return; must be compatible to a byte
     *
     * @param begin - a pointer to the beginning of the series
     * @param end - a pointer to the end of the series
     */
    template <typename T>
    void append(T* begin, T* end)
    {
        static_assert(
            std::is_same_v<utility::TypeIdDowncast_t<T>, int8_t> ||
                std::is_same_v<utility::TypeIdDowncast_t<T>, uint8_t> ||
                std::is_same_v<utility::TypeIdDowncast_t<T>, char>,
            "begin and end must be signed or unsigned byte pointers");
        // this interface only allows full-byte access; pack in partial bytes
        drain();
        raw.insert(raw.end(), reinterpret_cast<const uint8_t*>(begin),
                   reinterpret_cast<const uint8_t*>(end));
    }

    /**
     * @brief append a series of bits to the buffer
     *
     * Only the lowest @count order of bits will be appended, with the most
     * significant of those bits getting appended first.
     *
     * @param count - number of bits to append
     * @param bits - a byte with count significant bits to append
     */
    void appendBits(size_t count, uint8_t bits)
    {
        // drain whole bytes out
        drain(true);

        // add in the new bits as the higher-order bits, filling LSBit first
        fixed_uint_t<details::bitStreamSize> tmp = bits;
        tmp <<= bitCount;
        bitStream |= tmp;
        bitCount += count;

        // drain any whole bytes we have appended
        drain(true);
    }

    /**
     * @brief empty out the bucket and pack it as bytes LSB-first
     *
     * @param wholeBytesOnly - if true, only the whole bytes will be drained
     */
    void drain(bool wholeBytesOnly = false)
    {
        while (bitCount > 0)
        {
            uint8_t retVal;
            if (bitCount < CHAR_BIT)
            {
                if (wholeBytesOnly)
                {
                    break;
                }
            }
            size_t bitsOut = std::min(static_cast<size_t>(CHAR_BIT), bitCount);
            retVal = static_cast<uint8_t>(bitStream);
            raw.push_back(retVal);
            bitStream >>= bitsOut;
            bitCount -= bitsOut;
        }
    }

    // base empty pack
    int pack()
    {
        return 0;
    }

    /**
     * @brief pack arbitrary values (of any supported type) into the buffer
     *
     * @tparam Arg - the type of the first argument
     * @tparam Args - the type of the optional remaining arguments
     *
     * @param arg - the first argument to pack
     * @param args... - the optional remaining arguments to pack
     *
     * @return int - non-zero on pack errors
     */
    template <typename Arg, typename... Args>
    int pack(Arg&& arg, Args&&... args)
    {
        int packRet =
            details::PackSingle_t<Arg>::op(*this, std::forward<Arg>(arg));
        if (packRet)
        {
            return packRet;
        }
        packRet = pack(std::forward<Args>(args)...);
        drain();
        return packRet;
    }

    /**
     * @brief Prepends another payload to this one
     *
     * Avoid using this unless absolutely required since it inserts into the
     * front of the response payload.
     *
     * @param p - The payload to prepend
     *
     * @retunr int - non-zero on prepend errors
     */
    int prepend(const ipmi::message::Payload& p)
    {
        if (bitCount != 0 || p.bitCount != 0)
        {
            return 1;
        }
        raw.reserve(raw.size() + p.raw.size());
        raw.insert(raw.begin(), p.raw.begin(), p.raw.end());
        return 0;
    }

    /******************************************************************
     * Request operations
     *****************************************************************/
    /**
     * @brief pop a series of bytes from the raw buffer
     *
     * @tparam T - the type pointer to return; must be compatible to a byte
     *
     * @param count - the number of bytes to return
     *
     * @return - a tuple of pointers (begin,begin+count)
     */
    template <typename T>
    auto pop(size_t count)
    {
        static_assert(
            std::is_same_v<utility::TypeIdDowncast_t<T>, int8_t> ||
                std::is_same_v<utility::TypeIdDowncast_t<T>, uint8_t> ||
                std::is_same_v<utility::TypeIdDowncast_t<T>, char>,
            "T* must be signed or unsigned byte pointers");
        // this interface only allows full-byte access; skip partial bits
        if (bitCount)
        {
            // WARN on unused bits?
            discardBits();
        }
        if (count <= (raw.size() - rawIndex))
        {
            auto range = std::make_tuple(
                reinterpret_cast<T*>(raw.data() + rawIndex),
                reinterpret_cast<T*>(raw.data() + rawIndex + count));
            rawIndex += count;
            return range;
        }
        unpackError = true;
        return std::make_tuple(reinterpret_cast<T*>(NULL),
                               reinterpret_cast<T*>(NULL));
    }

    /**
     * @brief fill bit stream with at least count bits for consumption
     *
     * @param count - number of bit needed
     *
     * @return - unpackError
     */
    bool fillBits(size_t count)
    {
        // add more bits to the top end of the bitstream
        // so we consume bits least-significant first
        if (count > (details::bitStreamSize - CHAR_BIT))
        {
            unpackError = true;
            return unpackError;
        }
        while (bitCount < count)
        {
            if (rawIndex < raw.size())
            {
                fixed_uint_t<details::bitStreamSize> tmp = raw[rawIndex++];
                tmp <<= bitCount;
                bitStream |= tmp;
                bitCount += CHAR_BIT;
            }
            else
            {
                // raw has run out of bytes to pop
                unpackError = true;
                return unpackError;
            }
        }
        return false;
    }

    /**
     * @brief consume count bits from bitstream (must call fillBits first)
     *
     * @param count - number of bit needed
     *
     * @return - count bits from stream
     */
    uint8_t popBits(size_t count)
    {
        if (bitCount < count)
        {
            unpackError = true;
            return 0;
        }
        // consume bits low-order bits first
        auto bits = bitStream.convert_to<uint8_t>();
        bits &= ((1 << count) - 1);
        bitStream >>= count;
        bitCount -= count;
        return bits;
    }

    /**
     * @brief discard all partial bits
     */
    void discardBits()
    {
        bitStream = 0;
        bitCount = 0;
    }

    /**
     * @brief fully reset the unpack stream
     */
    void reset()
    {
        discardBits();
        rawIndex = 0;
        unpackError = false;
    }

    /**
     * @brief check to see if the stream has been fully unpacked
     *
     * @return bool - true if the stream has been unpacked and has no errors
     */
    bool fullyUnpacked()
    {
        unpackCheck = true;
        return raw.size() == rawIndex && bitCount == 0 && !unpackError;
    }

    // base empty unpack
    int unpack()
    {
        return 0;
    }

    /**
     * @brief unpack arbitrary values (of any supported type) from the buffer
     *
     * @tparam Arg - the type of the first argument
     * @tparam Args - the type of the optional remaining arguments
     *
     * @param arg - the first argument to unpack
     * @param args... - the optional remaining arguments to unpack
     *
     * @return int - non-zero for unpack error
     */
    template <typename Arg, typename... Args>
    int unpack(Arg&& arg, Args&&... args)
    {
        int unpackRet =
            details::UnpackSingle_t<Arg>::op(*this, std::forward<Arg>(arg));
        if (unpackRet)
        {
            unpackError = true;
            return unpackRet;
        }
        return unpack(std::forward<Args>(args)...);
    }

    /**
     * @brief unpack a tuple of values (of any supported type) from the buffer
     *
     * This will unpack the elements of the tuple as if each one was passed in
     * individually, as if passed into the above variadic function.
     *
     * @tparam Types - the implicitly declared list of the tuple element types
     *
     * @param t - the tuple of values to unpack
     *
     * @return int - non-zero on unpack error
     */
    template <typename... Types>
    int unpack(std::tuple<Types...>& t)
    {
        // roll back checkpoint so that unpacking a tuple is atomic
        size_t priorBitCount = bitCount;
        size_t priorIndex = rawIndex;
        fixed_uint_t<details::bitStreamSize> priorBits = bitStream;

        int ret =
            std::apply([this](Types&... args) { return unpack(args...); }, t);
        if (ret)
        {
            bitCount = priorBitCount;
            bitStream = priorBits;
            rawIndex = priorIndex;
        }

        return ret;
    }

    // partial bytes in the form of bits
    fixed_uint_t<details::bitStreamSize> bitStream;
    size_t bitCount = 0;
    SecureBuffer raw;
    size_t rawIndex = 0;
    bool trailingOk = true;
    bool unpackCheck = false;
    bool unpackError = false;
};

/**
 * @brief high-level interface to an IPMI response
 *
 * Make it easy to just pack in the response args from the callback into a
 * buffer that goes back to the requester.
 */
struct Response
{
    /* Define all of the basic class operations:
     *     Not allowed:
     *         - Default constructor to avoid nullptrs.
     *     Allowed:
     *         - Copy operations.
     *         - Move operations.
     *         - Destructor.
     */
    Response() = delete;
    Response(const Response&) = default;
    Response& operator=(const Response&) = default;
    Response(Response&&) = default;
    Response& operator=(Response&&) = default;
    ~Response() = default;

    using ptr = std::shared_ptr<Response>;

    explicit Response(Context::ptr& context) :
        payload(), ctx(context), cc(ccSuccess)
    {}

    /**
     * @brief pack arbitrary values (of any supported type) into the payload
     *
     * @tparam Args - the type of the optional arguments
     *
     * @param args... - the optional arguments to pack
     *
     * @return int - non-zero on pack errors
     */
    template <typename... Args>
    int pack(Args&&... args)
    {
        return payload.pack(std::forward<Args>(args)...);
    }

    /**
     * @brief pack a tuple of values (of any supported type) into the payload
     *
     * This will pack the elements of the tuple as if each one was passed in
     * individually, as if passed into the above variadic function.
     *
     * @tparam Types - the implicitly declared list of the tuple element types
     *
     * @param t - the tuple of values to pack
     *
     * @return int - non-zero on pack errors
     */
    template <typename... Types>
    int pack(std::tuple<Types...>& t)
    {
        return payload.pack(t);
    }

    /**
     * @brief Prepends another payload to this one
     *
     * Avoid using this unless absolutely required since it inserts into the
     * front of the response payload.
     *
     * @param p - The payload to prepend
     *
     * @retunr int - non-zero on prepend errors
     */
    int prepend(const ipmi::message::Payload& p)
    {
        return payload.prepend(p);
    }

    Payload payload;
    Context::ptr ctx;
    Cc cc;
};

/**
 * @brief high-level interface to an IPMI request
 *
 * Make it easy to unpack the buffer into the request args for the callback.
 */
struct Request
{
    /* Define all of the basic class operations:
     *     Not allowed:
     *         - Default constructor to avoid nullptrs.
     *     Allowed:
     *         - Copy operations.
     *         - Move operations.
     *         - Destructor.
     */
    Request() = delete;
    Request(const Request&) = default;
    Request& operator=(const Request&) = default;
    Request(Request&&) = default;
    Request& operator=(Request&&) = default;
    ~Request() = default;

    using ptr = std::shared_ptr<Request>;

    explicit Request(Context::ptr context, SecureBuffer&& d) :
        payload(std::forward<SecureBuffer>(d)), ctx(context)
    {}

    /**
     * @brief unpack arbitrary values (of any supported type) from the payload
     *
     * @tparam Args - the type of the optional arguments
     *
     * @param args... - the optional arguments to unpack
     *
     * @return int - non-zero for unpack error
     */
    template <typename... Args>
    int unpack(Args&&... args)
    {
        int unpackRet = payload.unpack(std::forward<Args>(args)...);
        if (unpackRet != ipmi::ccSuccess)
        {
            // not all bits were consumed by requested parameters
            return ipmi::ccReqDataLenInvalid;
        }
        if (!payload.trailingOk)
        {
            if (!payload.fullyUnpacked())
            {
                // not all bits were consumed by requested parameters
                return ipmi::ccReqDataLenInvalid;
            }
        }
        return ipmi::ccSuccess;
    }

    /**
     * @brief unpack a tuple of values (of any supported type) from the payload
     *
     * This will unpack the elements of the tuple as if each one was passed in
     * individually, as if passed into the above variadic function.
     *
     * @tparam Types - the implicitly declared list of the tuple element types
     *
     * @param t - the tuple of values to unpack
     *
     * @return int - non-zero on unpack error
     */
    template <typename... Types>
    int unpack(std::tuple<Types...>& t)
    {
        return std::apply([this](Types&... args) { return unpack(args...); },
                          t);
    }

    /** @brief Create a response message that corresponds to this request
     *
     * @return A shared_ptr to the response message created
     */
    Response::ptr makeResponse()
    {
        return std::make_shared<Response>(ctx);
    }

    Payload payload;
    Context::ptr ctx;
};

} // namespace message

} // namespace ipmi

// include packing and unpacking of types
#include <ipmid/message/pack.hpp>
#include <ipmid/message/unpack.hpp>
