// 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_"},      {3, "vout_margin_"},
        {4, "vout_setpoint_"}, {5, "nominal_target_vout_"}};

    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
