/*
 * 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 "config.h"

#include "buildjson.hpp"
#include "file_handler.hpp"
#include "firmware_handler.hpp"
#include "flags.hpp"
#include "general_systemd.hpp"
#include "image_handler.hpp"
#include "lpc_aspeed.hpp"
#include "lpc_handler.hpp"
#include "lpc_nuvoton.hpp"
#include "net_handler.hpp"
#include "pci_handler.hpp"
#include "status.hpp"
#include "util.hpp"

#include <sdbusplus/bus.hpp>

#include <cstdint>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

namespace ipmi_flash
{

namespace
{

static constexpr const char* jsonConfigurationPath =
    "/usr/share/phosphor-ipmi-flash/";

/**
 * Given a name and path, create a HandlerPack.
 *
 * @param[in] name - the blob id path for this
 * @param[in] path - the file path to write the contents.
 * @return the HandlerPack.
 */
HandlerPack CreateFileHandlerPack(const std::string& name,
                                  const std::string& path)
{
    return HandlerPack(name, std::make_unique<FileHandler>(path));
}

} // namespace
} // namespace ipmi_flash

extern "C"
{
    std::unique_ptr<blobs::GenericBlobInterface> createHandler();
}

std::unique_ptr<blobs::GenericBlobInterface> createHandler()
{
    using namespace ipmi_flash;

#ifdef NUVOTON_P2A_MBOX
    constexpr std::size_t memoryRegionSize = 16 * 1024UL;
#elif defined NUVOTON_P2A_VGA
    constexpr std::size_t memoryRegionSize = 4 * 1024 * 1024UL;
#else
    /* The maximum external buffer size we expect is 64KB. */
    constexpr std::size_t memoryRegionSize = 64 * 1024UL;
#endif

    std::vector<DataHandlerPack> supportedTransports;

    supportedTransports.emplace_back(FirmwareFlags::UpdateFlags::ipmi, nullptr);

#ifdef ENABLE_PCI_BRIDGE
    supportedTransports.emplace_back(
        FirmwareFlags::UpdateFlags::p2a,
        std::make_unique<PciDataHandler>(MAPPED_ADDRESS, memoryRegionSize));
#endif

#ifdef ENABLE_LPC_BRIDGE
#if defined(ASPEED_LPC)
    supportedTransports.emplace_back(
        FirmwareFlags::UpdateFlags::lpc,
        std::make_unique<LpcDataHandler>(LpcMapperAspeed::createAspeedMapper(
            MAPPED_ADDRESS, memoryRegionSize)));
#elif defined(NUVOTON_LPC)
    supportedTransports.emplace_back(
        FirmwareFlags::UpdateFlags::lpc,
        std::make_unique<LpcDataHandler>(LpcMapperNuvoton::createNuvotonMapper(
            MAPPED_ADDRESS, memoryRegionSize)));
#else
#error "You must specify a hardware implementation."
#endif
#endif

#ifdef ENABLE_NET_BRIDGE
    supportedTransports.emplace_back(FirmwareFlags::UpdateFlags::net,
                                     std::make_unique<NetDataHandler>());
#endif

    ActionMap actionPacks = {};

    std::vector<HandlerConfig> configsFromJson =
        BuildHandlerConfigs(jsonConfigurationPath);

    std::vector<HandlerPack> supportedFirmware;

    supportedFirmware.push_back(
        std::move(CreateFileHandlerPack(hashBlobId, HASH_FILENAME)));

    for (auto& config : configsFromJson)
    {
        supportedFirmware.push_back(
            std::move(HandlerPack(config.blobId, std::move(config.handler))));
        actionPacks[config.blobId] = std::move(config.actions);

        std::fprintf(stderr, "config loaded: %s\n", config.blobId.c_str());
    }

    auto handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(
        std::move(supportedFirmware), std::move(supportedTransports),
        std::move(actionPacks));

    if (!handler)
    {
        std::fprintf(stderr, "Firmware Handler has an invalid configuration");
        return nullptr;
    }

    return handler;
}
