// Copyright 2023 Google LLC
//
// 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 "bifurcation.hpp"
#include "file_system_wrapper_impl.hpp"
#include "handler.hpp"

#include <nlohmann/json.hpp>
#include <sdbusplus/bus.hpp>

#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <vector>

namespace google
{
namespace ipmi
{

constexpr char defaultConfigFile[] =
    "/usr/share/ipmi-entity-association/entity_association_map.json";

class Handler : public HandlerInterface
{
  public:
    explicit Handler(const std::string& entityConfigPath = defaultConfigFile) :
        fsPtr(std::make_unique<FileSystemWrapper>()),
        _configFile(entityConfigPath),
        bifurcationHelper(BifurcationStatic::createBifurcation()) {};
    Handler(std::reference_wrapper<BifurcationInterface> bifurcationHelper,
            const std::string& entityConfigPath = defaultConfigFile) :
        fsPtr(std::make_unique<FileSystemWrapper>()),
        _configFile(entityConfigPath), bifurcationHelper(bifurcationHelper) {};
    ~Handler() = default;

    uint8_t getBmcMode() override;
    std::tuple<std::uint8_t, std::string>
        getEthDetails(std::string intf) const override;
    std::int64_t getRxPackets(const std::string& name) const override;
    VersionTuple getCpldVersion(unsigned int id) const override;
    void psuResetDelay(std::uint32_t delay) const override;
    void psuResetOnShutdown() const override;
    std::string getEntityName(std::uint8_t id, std::uint8_t instance) override;
    uint32_t getFlashSize() override;
    std::string getMachineName() override;
    void buildI2cPcieMapping() override;
    size_t getI2cPcieMappingSize() const override;
    void hostPowerOffDelay(std::uint32_t delay) const override;
    std::tuple<std::uint32_t, std::string>
        getI2cEntry(unsigned int entry) const override;
    std::vector<uint8_t> pcieBifurcation(uint8_t) override;

    uint32_t accelOobDeviceCount() const override;
    std::string accelOobDeviceName(size_t index) const override;
    uint64_t accelOobRead(std::string_view name, uint64_t address,
                          uint8_t num_bytes) const override;
    void accelOobWrite(std::string_view name, uint64_t address,
                       uint8_t num_bytes, uint64_t data) const override;
    void linuxBootDone() const override;
    void accelSetVrSettings(::ipmi::Context::ptr ctx, uint8_t chip_id,
                            uint8_t settings_id, uint16_t value) const override;
    uint16_t accelGetVrSettings(::ipmi::Context::ptr ctx, uint8_t chip_id,
                                uint8_t settings_id) const override;
    std::string getBMInstanceProperty(uint8_t propertyType) const override;

  protected:
    // Exposed for dependency injection
    virtual sdbusplus::bus_t getDbus() const;
    virtual const std::unique_ptr<FileSystemInterface>& getFs() const;

  private:
    std::unique_ptr<FileSystemInterface> fsPtr;

    std::string _configFile;

    bool _entityConfigParsed = false;

    const std::map<uint8_t, std::string> _entityIdToName{
        {0x03, "cpu"},
        {0x04, "storage_device"},
        {0x06, "system_management_module"},
        {0x07, "system_board"},
        {0x08, "memory_module"},
        {0x0B, "add_in_card"},
        {0x0E, "power_system_board"},
        {0x10, "system_internal_expansion_board"},
        {0x11, "other_system_board"},
        {0x17, "system_chassis"},
        {0x1D, "fan"},
        {0x1E, "cooling_unit"},
        {0x20, "memory_device"}};

    const std::unordered_map<uint8_t, std::string> _vrSettingsMap{
        {0, "idle_mode_"}, {1, "power_brake_"}, {2, "loadline_"}};

    const std::unordered_map<uint8_t, std::string> bmInstanceTypeStringMap = {
        {0x00, "asset-tag"}, {0x01, "board-serial-number"},
        {0x02, "family"},    {0x03, "product-name"},
        {0x04, "sku"},       {0x05, "system-serial-number"},
        {0x06, "uuid"}};

    nlohmann::json _entityConfig{};

    std::vector<std::tuple<uint32_t, std::string>> _pcie_i2c_map;

    std::reference_wrapper<BifurcationInterface> bifurcationHelper;
};

/**
 * Given a type, entity instance, and a configuration, return the name.
 *
 * @param[in] type - the entity type
 * @param[in] instance - the entity instance
 * @param[in] config - the json object holding the entity mapping
 * @return the name of the entity from the map
 */
std::string readNameFromConfig(const std::string& type, uint8_t instance,
                               const nlohmann::json& config);

} // namespace ipmi
} // namespace google
