/**
 * Copyright © 2017 IBM 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.
 */

#include "config.h"

#include "event_manager.hpp"

#include "event.hpp"
#include "event_serialize.hpp"

#include <filesystem>

namespace phosphor
{
namespace events
{

void Manager::create(const std::string& eventName,
                     const std::string& eventMessage,
                     const std::string& objectPath,
                     const std::string& propertyName,
                     const std::string& propertyValue)
{
    using namespace std::string_literals;
    namespace fs = std::filesystem;

    auto msg = eventMessage;
    std::vector<std::string> additionalData;

    auto propVal = propertyName + "=" + propertyValue;
    auto path = "path="s + objectPath;

    additionalData.push_back(std::move(path));
    additionalData.push_back(std::move(propVal));

    auto& eventQueue = eventMap[eventName];

    // get the last event entry for this event
    // to generate the id.
    auto id = 0;
    if (eventQueue.size() > 0)
    {
        fs::path eventPath(eventQueue.back()->objectPath);
        id = std::stoi(std::string(eventPath.filename().c_str()));
        id++;
    }

    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                  std::chrono::system_clock::now().time_since_epoch())
                  .count();

    auto objPath = std::string(OBJ_EVENT) + '/' + eventName + '/' +
                   std::to_string(id);

    // check for capping of the events,if cap reached then erase the oldest
    // event.
    if (eventQueue.size() == MAX_EVENTS)
    {
        fs::path eventPath(EVENTS_PERSIST_PATH);
        eventPath /= eventName;
        eventPath /= std::to_string(eventQueue.front()->timestamp());
        eventQueue.pop();
        std::error_code ec;
        fs::remove(eventPath, ec);
    }

    auto event = std::make_unique<Entry>(
        objPath,
        ms, // Milliseconds since 1970
        std::move(msg), std::move(additionalData));
    serialize(*event, eventName);
    eventQueue.push(std::move(event));
}

void Manager::restore()
{
    if (!fs::exists(EVENTS_PERSIST_PATH) || fs::is_empty(EVENTS_PERSIST_PATH))
    {
        return;
    }

    for (auto& eventFile :
         fs::recursive_directory_iterator(EVENTS_PERSIST_PATH))
    {
        if (!fs::is_regular_file(eventFile))
        {
            continue;
        }

        EventQueue events;

        auto eventPath = eventFile.path().string();
        auto pos1 = eventPath.rfind("/");
        auto pos2 = eventPath.rfind("/", pos1 - 1) + 1;
        auto eventName = eventPath.substr(pos2, (pos1 - pos2));
        auto validEvent = false;
        auto timestamp = eventFile.path().filename().string();
        auto tsNum = std::stoll(timestamp);
        auto objPath = std::string(OBJ_EVENT) + '/' + eventName + '/' +
                       timestamp;

        auto event = std::make_unique<Entry>(objPath, tsNum);
        if (deserialize(eventFile.path(), *event))
        {
            event->emit_object_added();
            events.push(std::move(event));
            validEvent = true;
        }

        if (validEvent)
        {
            eventMap[eventName] = std::move(events);
        }
    }
}

Manager& getManager()
{
    static Manager mgr;
    return mgr;
}

} // namespace events
} // namespace phosphor
