/*
 * Copyright 2019 Google Inc.
 *
 * 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 "helper.hpp"

#include "status.hpp"
#include "tool_errors.hpp"

#include <ipmiblob/blob_errors.hpp>
#include <ipmiblob/blob_interface.hpp>

#include <algorithm>
#include <chrono>
#include <optional>
#include <thread>
#include <utility>

namespace host_tool
{

template <typename Check>
static auto pollStat(std::uint16_t session, ipmiblob::BlobInterface* blob,
                     Check&& check)
{
    using namespace std::chrono_literals;

    constexpr auto maxSleep = 1s;
    constexpr auto printInterval = 30s;
    constexpr auto timeout = 30min;

    try
    {
        auto start = std::chrono::steady_clock::now();
        auto last_print = start;
        auto last_check = start;
        auto check_interval = 50ms;

        while (true)
        {
            ipmiblob::StatResponse resp = blob->getStat(session);
            auto ret = check(resp);
            if (ret.has_value())
            {
                std::fprintf(stderr, "success\n");
                return std::move(*ret);
            }

            auto cur = std::chrono::steady_clock::now();
            if (cur - last_print >= printInterval)
            {
                std::fprintf(stderr, "running\n");
                last_print = cur;
            }

            auto sleep = check_interval - (cur - last_check);
            last_check = cur;
            // Check that we don't timeout immediately after sleeping
            // to avoid an extra sleep without checking
            if (cur - start > timeout - sleep)
            {
                throw ToolException("Stat check timed out");
            }
            check_interval = std::min<decltype(check_interval)>(
                check_interval * 2, maxSleep);
            std::this_thread::sleep_for(sleep);
        }
    }
    catch (const ipmiblob::BlobException& b)
    {
        throw ToolException("blob exception received: " +
                            std::string(b.what()));
    }
}

/* Poll an open verification session.  Handling closing the session is not yet
 * owned by this method.
 */
void pollStatus(std::uint16_t session, ipmiblob::BlobInterface* blob)
{
    pollStat(session, blob,
             [](const ipmiblob::StatResponse& resp) -> std::optional<bool> {
                 if (resp.metadata.size() != 1)
                 {
                     throw ToolException("Invalid stat metadata");
                 }
                 auto result =
                     static_cast<ipmi_flash::ActionStatus>(resp.metadata[0]);
                 switch (result)
                 {
                     case ipmi_flash::ActionStatus::failed:
                         throw ToolException("BMC reported failure");
                     case ipmi_flash::ActionStatus::unknown:
                     case ipmi_flash::ActionStatus::running:
                         return std::nullopt;
                     case ipmi_flash::ActionStatus::success:
                         return true;
                     default:
                         throw ToolException("Unrecognized action status");
                 }
             });
}

/* Poll an open blob session for reading.
 *
 * The committing bit indicates that the blob is not available for reading now
 * and the reader might come back and check the state later.
 *
 * Polling finishes under the following conditions:
 * - The open_read bit set -> stat successful
 * - The open_read and committing bits unset -> stat failed;
 * - Blob exception was received;
 * - Time ran out.
 * Polling continues when the open_read bit unset and committing bit set.
 * If the blob is not open_read and not committing, then it is an error to the
 * reader.
 */
uint32_t pollReadReady(std::uint16_t session, ipmiblob::BlobInterface* blob)
{
    return pollStat(
        session, blob,
        [](const ipmiblob::StatResponse& resp) -> std::optional<uint32_t> {
            if (resp.blob_state & ipmiblob::StateFlags::open_read)
            {
                return resp.size;
            }
            if (resp.blob_state & ipmiblob::StateFlags::committing)
            {
                return std::nullopt;
            }
            throw ToolException("BMC blob failed to become ready");
        });
}

void* memcpyAligned(void* destination, const void* source, std::size_t size)
{
    std::size_t i = 0;
    std::size_t bytesCopied = 0;

    if (!(reinterpret_cast<std::uintptr_t>(destination) %
          sizeof(std::uint64_t)) &&
        !(reinterpret_cast<std::uintptr_t>(source) % sizeof(std::uint64_t)))
    {
        auto src64 = reinterpret_cast<const volatile std::uint64_t*>(source);
        auto dest64 = reinterpret_cast<volatile std::uint64_t*>(destination);

        for (i = 0; i < size / sizeof(std::uint64_t); i++)
        {
            *dest64++ = *src64++;
            bytesCopied += sizeof(std::uint64_t);
        }
    }

    auto srcMem8 =
        reinterpret_cast<const volatile std::uint8_t*>(source) + bytesCopied;
    auto destMem8 =
        reinterpret_cast<volatile std::uint8_t*>(destination) + bytesCopied;

    for (i = bytesCopied; i < size; i++)
    {
        *destMem8++ = *srcMem8++;
    }

    return destination;
}

} // namespace host_tool
