/*
 * Copyright 2018 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 "updater.hpp"

#include "firmware_handler.hpp"
#include "tool_errors.hpp"

#include <algorithm>
#include <blobs-ipmid/blobs.hpp>
#include <cstring>
#include <ipmiblob/blob_errors.hpp>
#include <memory>
#include <string>
#include <thread>

namespace host_tool
{

/* Poll an open verification session.  Handling closing the session is not yet
 * owned by this method. */
bool pollVerificationStatus(std::uint16_t session,
                            ipmiblob::BlobInterface* blob)
{
    using namespace std::chrono_literals;

    static constexpr auto verificationSleep = 5s;
    static constexpr int commandAttempts = 20;
    int attempts = 0;
    bool exitLoop = false;
    blobs::FirmwareBlobHandler::VerifyCheckResponses result =
        blobs::FirmwareBlobHandler::VerifyCheckResponses::other;

    try
    {
        /* Reach back the current status from the verification service output.
         */
        while (attempts++ < commandAttempts)
        {
            ipmiblob::StatResponse resp = blob->getStat(session);

            if (resp.metadata.size() != sizeof(std::uint8_t))
            {
                /* TODO: How do we want to handle the verification failures,
                 * because closing the session to the verify blob has a special
                 * as-of-yet not fully defined behavior.
                 */
                std::fprintf(stderr, "Received invalid metadata response!!!\n");
            }

            result =
                static_cast<blobs::FirmwareBlobHandler::VerifyCheckResponses>(
                    resp.metadata[0]);

            switch (result)
            {
                case blobs::FirmwareBlobHandler::VerifyCheckResponses::failed:
                    std::fprintf(stderr, "failed\n");
                    exitLoop = true;
                    break;
                case blobs::FirmwareBlobHandler::VerifyCheckResponses::other:
                    std::fprintf(stderr, "other\n");
                    break;
                case blobs::FirmwareBlobHandler::VerifyCheckResponses::running:
                    std::fprintf(stderr, "running\n");
                    break;
                case blobs::FirmwareBlobHandler::VerifyCheckResponses::success:
                    std::fprintf(stderr, "success\n");
                    exitLoop = true;
                    break;
                default:
                    std::fprintf(stderr, "wat\n");
            }

            if (exitLoop)
            {
                break;
            }
            std::this_thread::sleep_for(verificationSleep);
        }
    }
    catch (const ipmiblob::BlobException& b)
    {
        throw ToolException("blob exception received: " +
                            std::string(b.what()));
    }

    /* TODO: If this is reached and it's not success, it may be worth just
     * throwing a ToolException with a timeout message specifying the final
     * read's value.
     *
     * TODO: Given that excepting from certain points leaves the BMC update
     * state machine in an inconsistent state, we need to carefully evaluate
     * which exceptions from the lower layers allow one to try and delete the
     * blobs to rollback the state and progress.
     */
    return (result ==
            blobs::FirmwareBlobHandler::VerifyCheckResponses::success);
}

void updaterMain(ipmiblob::BlobInterface* blob, DataInterface* handler,
                 const std::string& imagePath, const std::string& signaturePath)
{
    /* TODO(venture): Add optional parameter to specify the flash type, default
     * to legacy for now.
     *
     * TODO(venture): Move the strings from the FirmwareHandler object to a
     * boring utils object so it will be more happly linked cleanly to both the
     * BMC and host-side.
     */
    std::string goalFirmware = "/flash/image";
    std::string hashFilename = "/flash/hash";
    std::string verifyFilename = "/flash/verify";

    /* Get list of blob_ids, check for /flash/image, or /flash/tarball.
     * TODO(venture) the mechanism doesn't care, but the caller of burn_my_bmc
     * will have in mind which they're sending and we need to verify it's
     * available and use it.
     */
    std::vector<std::string> blobs = blob->getBlobList();
    auto blobInst = std::find_if(
        blobs.begin(), blobs.end(), [&goalFirmware](const std::string& iter) {
            /* Running into weird scenarios where the string comparison doesn't
             * work.  TODO: revisit.
             */
            return (0 == std::memcmp(goalFirmware.c_str(), iter.c_str(),
                                     goalFirmware.length()));
            // return (goalFirmware.compare(iter));
        });
    if (blobInst == blobs.end())
    {
        throw ToolException(goalFirmware + " not found");
    }

    /* Call stat on /flash/image (or /flash/tarball) and check if data interface
     * is supported.
     */
    ipmiblob::StatResponse stat;
    try
    {
        stat = blob->getStat(goalFirmware);
    }
    catch (const ipmiblob::BlobException& b)
    {
        throw ToolException("blob exception received: " +
                            std::string(b.what()));
    }

    auto supported = handler->supportedType();
    if ((stat.blob_state & supported) == 0)
    {
        throw ToolException("data interface selected not supported.");
    }

    /* Yay, our data handler is supported. */

    /* Send over the firmware image. */
    std::fprintf(stderr, "Sending over the firmware image.\n");
    std::uint16_t session;
    try
    {
        session = blob->openBlob(
            goalFirmware,
            static_cast<std::uint16_t>(supported) |
                static_cast<std::uint16_t>(blobs::OpenFlags::write));
    }
    catch (const ipmiblob::BlobException& b)
    {
        throw ToolException("blob exception received: " +
                            std::string(b.what()));
    }

    if (!handler->sendContents(imagePath, session))
    {
        /* Need to close the session on failure, or it's stuck open (until the
         * blob handler timeout is implemented, and even then, why make it wait.
         */
        blob->closeBlob(session);
        throw ToolException("Failed to send contents of " + imagePath);
    }

    blob->closeBlob(session);

    /* Send over the hash contents. */
    std::fprintf(stderr, "Sending over the hash file.\n");
    try
    {
        session = blob->openBlob(
            hashFilename,
            static_cast<std::uint16_t>(supported) |
                static_cast<std::uint16_t>(blobs::OpenFlags::write));
    }
    catch (const ipmiblob::BlobException& b)
    {
        throw ToolException("blob exception received: " +
                            std::string(b.what()));
    }

    if (!handler->sendContents(signaturePath, session))
    {
        blob->closeBlob(session);
        throw ToolException("Failed to send contents of " + signaturePath);
    }

    blob->closeBlob(session);

    /* Trigger the verification by opening the verify file. */
    std::fprintf(stderr, "Opening the verification file\n");
    try
    {
        session = blob->openBlob(
            verifyFilename,
            static_cast<std::uint16_t>(supported) |
                static_cast<std::uint16_t>(blobs::OpenFlags::write));
    }
    catch (const ipmiblob::BlobException& b)
    {
        throw ToolException("blob exception received: " +
                            std::string(b.what()));
    }

    std::fprintf(
        stderr,
        "Committing to verification file to trigger verification service\n");
    try
    {
        blob->commit(session, {});
    }
    catch (const ipmiblob::BlobException& b)
    {
        throw ToolException("blob exception received: " +
                            std::string(b.what()));
    }

    std::fprintf(stderr,
                 "Calling stat on verification session to check status\n");

    if (pollVerificationStatus(session, blob))
    {
        std::fprintf(stderr, "Verification returned success\n");
    }
    else
    {
        std::fprintf(stderr, "Verification returned non-success (could still "
                             "be running (unlikely))\n");
    }

    /* DO NOT CLOSE the verification session until it's done.
     * TODO: Evaluate what closing verification should do?  If the process is
     * complete, nothing bad, maybe reset the entire state machine?  This will
     * benefit from a diagram.
     */
    blob->closeBlob(session);

    return;
}

} // namespace host_tool
