// SPDX-License-Identifier: Unlicense

#include "stats.h"

#include "file.h"
#include "global.h"
#include "ini.h"
#include "string_.h"

static std::map<std::string, std::map<std::string, std::string>> serialize(SongIndex songIndex)
{
  const std::vector<Arrangement::Info>& arrangementInfos = Global::songInfos[songIndex].arrangementInfos;

  std::map<std::string, std::map<std::string, std::string>> serializedSaves;

  for (const auto& arrangementInfo : arrangementInfos)
  {
    std::map<std::string, std::string> serializedSave;

    if (Global::songStats.contains(arrangementInfo.persistentId))
    {
      const SongStats& songStats = Global::songStats.at(arrangementInfo.persistentId);

      if (songStats.lastPlayed > 0)
      {
        serializedSave.insert({ "LastPlayed", to_string(songStats.lastPlayed) });
      }
      if (songStats.timePlayed > 0)
      {
        serializedSave.insert({ "TimePlayed", TimeNS_To_String(songStats.timePlayed) });
      }
      if (songStats.sfxBankIndex >= 0)
      {
        serializedSave.insert({ "ToneBank", to_string(songStats.sfxBankIndex) });
      }
    }

    if (serializedSave.size() >= 1)
      serializedSaves.insert({ arrangementInfo.persistentId, serializedSave });
  }

  return serializedSaves;
}

static void loadSongStats(const std::pair<std::string, std::map<std::string, std::string>>& entry)
{
  SongStats& songStats = Global::songStats[entry.first];
  if (entry.second.contains("LastPlayed"))
    songStats.lastPlayed = atoi(entry.second.at("LastPlayed").c_str());
  if (entry.second.contains("TimePlayed"))
    songStats.timePlayed = timeNS_From_String(entry.second.at("TimePlayed").c_str());
  if (entry.second.contains("ToneBank"))
    songStats.sfxBankIndex = atoi(entry.second.at("ToneBank").c_str());
}

void Stats::init()
{
  if (!File::exists(Settings::pathStatsIni.c_str()))
    return;

  const std::vector<u8> statsIniData = File::read(Settings::pathStatsIni.c_str());
  const std::map<std::string, std::map<std::string, std::string>> serializedSaves = Ini::loadIniContent((const char*)statsIniData.data(), statsIniData.size());

  for (const std::pair<std::string, std::map<std::string, std::string>> pair : serializedSaves)
  {
    loadSongStats(pair);
  }
}

void Stats::fini()
{
  std::map<std::string, std::map<std::string, std::string>> serializedSaves;

  for (SongIndex songIndex = 0; songIndex < SongIndex(Global::songInfos.size()); ++songIndex)
  {
    const std::map<std::string, std::map<std::string, std::string>> map = serialize(songIndex);
    serializedSaves.insert(map.begin(), map.end());
  }

  Ini::saveIniFile(Settings::pathStatsIni.c_str(), serializedSaves);
}
