/*
 *  Copyright (C) 2013-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#include "ContextMenuAddon.h"

#include "ContextMenuItem.h"
#include "ContextMenuManager.h"
#include "ServiceBroker.h"
#include "addons/addoninfo/AddonType.h"
#include "resources/LocalizeStrings.h"
#include "resources/ResourcesComponent.h"
#include "utils/StringUtils.h"
#include "utils/URIUtils.h"

#include <sstream>

namespace ADDON
{

CContextMenuAddon::CContextMenuAddon(const AddonInfoPtr& addonInfo)
  : CAddon(addonInfo, AddonType::CONTEXTMENU_ITEM)
{
  const CAddonExtensions* menu = Type(AddonType::CONTEXTMENU_ITEM)->GetElement("menu");
  if (menu)
  {
    int tmp = 0;
    ParseMenu(menu, "", tmp);
  }
  else
  {
    //backwards compatibility. add first item definition
    const CAddonExtensions* elem = Type(AddonType::CONTEXTMENU_ITEM)->GetElement("item");
    if (elem)
    {
      std::string visCondition = elem->GetValue("visible").asString();
      if (visCondition.empty())
        visCondition = "false";

      std::string parent = elem->GetValue("parent").asString() == "kodi.core.manage"
          ? CContextMenuManager::MANAGE.m_groupId : CContextMenuManager::MAIN.m_groupId;

      std::string label = elem->GetValue("label").asString();
      if (StringUtils::IsNaturalNumber(label))
        label = CServiceBroker::GetResourcesComponent().GetLocalizeStrings().GetAddonString(
            ID(), atoi(label.c_str()));

      m_items.emplace_back(CContextMenuItem::CItem{
          .label = std::move(label),
          .parent = std::move(parent),
          .library =
              URIUtils::AddFileToFolder(Path(), Type(AddonType::CONTEXTMENU_ITEM)->LibName()),
          .condition = std::move(visCondition),
          .addonId = ID()});
    }
  }
}

CContextMenuAddon::~CContextMenuAddon() = default;

void CContextMenuAddon::ParseMenu(
    const CAddonExtensions* elem,
    const std::string& parent,
    int& anonGroupCount)
{
  std::string menuId = elem->GetValue("@id").asString();
  std::string menuLabel = elem->GetValue("label").asString();
  if (StringUtils::IsNaturalNumber(menuLabel))
    menuLabel = CServiceBroker::GetResourcesComponent().GetLocalizeStrings().GetAddonString(
        ID(), std::stoi(menuLabel));

  if (menuId.empty())
  {
    //anonymous group. create a new unique internal id.
    anonGroupCount++;
    std::stringstream ss;
    ss << ID() << anonGroupCount;
    menuId = ss.str();
  }

  m_items.emplace_back(CContextMenuItem::CGroup{
      .label = std::move(menuLabel), .parent = parent, .groupId = menuId, .addonId = ID()});

  for (const auto& [_, addonExtensions] : elem->GetElements("menu"))
    ParseMenu(&addonExtensions, menuId, anonGroupCount);

  for (const auto& [_, addonExtensions] : elem->GetElements("item"))
  {
    std::string visCondition = addonExtensions.GetValue("visible").asString();
    std::string library = addonExtensions.GetValue("@library").asString();
    std::string label = addonExtensions.GetValue("label").asString();
    if (StringUtils::IsNaturalNumber(label))
      label = CServiceBroker::GetResourcesComponent().GetLocalizeStrings().GetAddonString(
          ID(), std::atoi(label.c_str()));

    std::vector<std::string> args;
    args.emplace_back(ID());

    const std::string arg = addonExtensions.GetValue("@args").asString();
    if (!arg.empty())
      args.emplace_back(arg);

    if (!label.empty() && !library.empty() && !visCondition.empty())
    {
      m_items.emplace_back(
          CContextMenuItem::CItem{.label = std::move(label),
                                  .parent = menuId,
                                  .library = URIUtils::AddFileToFolder(Path(), library),
                                  .condition = std::move(visCondition),
                                  .addonId = ID(),
                                  .args = std::move(args)});
    }
  }
}

} // namespace ADDON
