/*
// Copyright (c) 2019 Intel Corporation
//
// 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 <config.h>
#include <fcntl.h>
#include <unistd.h>

#include <phosphor-logging/elog-errors.hpp>
#include <sdbusplus/timer.hpp>
#include <xyz/openbmc_project/Collection/DeleteAll/server.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
#include <xyz/openbmc_project/State/Boot/PostCode/server.hpp>
#include <xyz/openbmc_project/State/Host/server.hpp>

#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>

const static constexpr char* CurrentBootCycleCountName =
    "CurrentBootCycleCount";
const static constexpr char* CurrentBootCycleIndexName =
    "CurrentBootCycleIndex";

const static constexpr char* PostCodePath =
    "/xyz/openbmc_project/state/boot/raw";
const static constexpr char* PostCodeListPathPrefix =
    "/var/lib/phosphor-post-code-manager/host";
const static constexpr char* HostStatePathPrefix =
    "/xyz/openbmc_project/state/host";

struct EventDeleter
{
    void operator()(sd_event* event) const
    {
        sd_event_unref(event);
    }
};
using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
using primarycode_t = uint64_t;
using secondarycode_t = std::vector<uint8_t>;
using postcode_t = std::tuple<primarycode_t, secondarycode_t>;
namespace fs = std::filesystem;
namespace StateServer = sdbusplus::xyz::openbmc_project::State::server;

using post_code =
    sdbusplus::xyz::openbmc_project::State::Boot::server::PostCode;
using delete_all =
    sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll;

struct PostCode : sdbusplus::server::object_t<post_code, delete_all>
{
    PostCode(sdbusplus::bus_t& bus, const char* path, EventPtr& event,
             int nodeIndex) :
        sdbusplus::server::object_t<post_code, delete_all>(bus, path),
        bus(bus), event(event), node(nodeIndex),
        postCodeListPath(PostCodeListPathPrefix + std::to_string(node)),
        propertiesChangedSignalRaw(
            bus,
            sdbusplus::bus::match::rules::propertiesChanged(
                PostCodePath + std::to_string(node),
                "xyz.openbmc_project.State.Boot.Raw"),
            [this](sdbusplus::message_t& msg) {
        std::string intfName;
        std::map<std::string, std::variant<postcode_t>> msgData;
        msg.read(intfName, msgData);
        // Check if it was the Value property that changed.
        auto valPropMap = msgData.find("Value");
        if (valPropMap != msgData.end())
        {
            this->savePostCodes(std::get<postcode_t>(valPropMap->second));
        }
    }),
        propertiesChangedSignalCurrentHostState(
            bus,
            sdbusplus::bus::match::rules::propertiesChanged(
                HostStatePathPrefix + std::to_string(node),
                "xyz.openbmc_project.State.Host"),
            [this](sdbusplus::message_t& msg) {
        std::string intfName;
        std::map<std::string, std::variant<std::string>> msgData;
        msg.read(intfName, msgData);
        // Check if it was the Value property that changed.
        auto valPropMap = msgData.find("CurrentHostState");
        if (valPropMap != msgData.end())
        {
            StateServer::Host::HostState currentHostState =
                StateServer::Host::convertHostStateFromString(
                    std::get<std::string>(valPropMap->second));
            if (currentHostState == StateServer::Host::HostState::Off)
            {
                if (this->postCodes.empty())
                {
                    std::cerr << "HostState changed to OFF. Empty "
                                 "postcode log, keep boot cycle at "
                              << this->currentBootCycleIndex << std::endl;
                }
                else
                {
                    this->postCodes.clear();
                }
            }
        }
    })
    {
        phosphor::logging::log<phosphor::logging::level::INFO>(
            "PostCode is created");
        fs::create_directories(postCodeListPath);
        deserialize(postCodeListPath / CurrentBootCycleIndexName,
                    currentBootCycleIndex);
        uint16_t count = 0;
        deserialize(postCodeListPath / CurrentBootCycleCountName, count);
        currentBootCycleCount(count);
        maxBootCycleNum(MAX_BOOT_CYCLE_COUNT);
    }
    ~PostCode() {}

    std::vector<postcode_t> getPostCodes(uint16_t index) override;
    std::map<uint64_t, postcode_t>
        getPostCodesWithTimeStamp(uint16_t index) override;
    void deleteAll() override;

  private:
    void incrBootCycle();
    uint16_t getBootNum(const uint16_t index) const;

    std::unique_ptr<sdbusplus::Timer> timer;
    sdbusplus::bus_t& bus;
    EventPtr& event;
    int node;
    std::chrono::time_point<std::chrono::steady_clock> firstPostCodeTimeSteady;
    uint64_t firstPostCodeUsSinceEpoch;
    std::map<uint64_t, postcode_t> postCodes;
    fs::path postCodeListPath;
    uint16_t currentBootCycleIndex = 0;
    sdbusplus::bus::match_t propertiesChangedSignalRaw;
    sdbusplus::bus::match_t propertiesChangedSignalCurrentHostState;

    void savePostCodes(postcode_t code);
    fs::path serialize(const fs::path& path);
    bool deserialize(const fs::path& path, uint16_t& index);
    bool deserializePostCodes(const fs::path& path,
                              std::map<uint64_t, postcode_t>& codes);
};
