// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Mobius Forensic Toolkit
// Copyright (C) 2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024 Eduardo Aguiar
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include "common.h"
#include <mobius/core/log.h>
#include <mobius/decoder/data_decoder.h>
#include <mobius/pod/data.h>
#include <vector>

namespace mobius::extension::app::ares
{
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief Decrypt data
//! \param enc_data Encrypted data
//! \return Decrypted data
//! \see helper_library_db.pas
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
mobius::bytearray
decrypt (const mobius::bytearray& enc_data, std::uint16_t seed)
{
  mobius::bytearray data (enc_data.size ());
  auto iter = data.begin ();

  for (auto c : enc_data)
    {
      *iter = (c ^ (seed >> 8));
      seed = (c + seed) * 23219 + 36126;
      ++iter;
    }

  return data;
}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief Convert media type to string
//! \param t Media type
//! \see mediatype_to_str function (helper_mimetypes.pas)
//! \see const_ares.pas
//! \see vars_localiz.pas
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
std::string
media_type_to_string (std::uint8_t t)
{
  mobius::core::log log (__FILE__, __FUNCTION__);

  switch (t)
  {
    case 0: return "Other"; break;
    case 1: return "Audio"; break;
    case 2: return "Audio"; break;
    case 3: return "Software"; break;
    case 4: return "Audio"; break;
    case 5: return "Video"; break;
    case 6: return "Document"; break;
    case 7: return "Image"; break;

    default:
      log.development (__LINE__, "unhandled media type: " + std::to_string (t));
      return {};
  };
}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief Decoder old altsources
//! \param data Encoded data
//! \return Alt sources
//! \see add_sources function @helper_altsources (line 106)
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
std::vector <std::pair <std::string, std::uint16_t>>
decode_old_alt_sources (const mobius::bytearray& data)
{
  std::vector <std::pair <std::string, std::uint16_t>> sources;
  auto decoder = mobius::decoder::data_decoder (data);

  while (decoder)
    {
      auto ip = decoder.get_ipv4_be ();
      auto port = decoder.get_uint16_le ();
      sources.emplace_back (ip, port);
      decoder.skip (6);  // ip_server, port_server
    }

  return sources;
}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief Decoder altsources
//! \param data Encoded data
//! \return Alt sources
//! \see add_sources function @helper_altsources (line 106)
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
std::vector <std::pair <std::string, std::uint16_t>>
decode_alt_sources (const mobius::bytearray& data)
{
  std::vector <std::pair <std::string, std::uint16_t>> sources;
  auto decoder = mobius::decoder::data_decoder (data);

  while (decoder)
    {
      auto ip = decoder.get_ipv4_be ();
      auto port = decoder.get_uint16_le ();
      sources.emplace_back (ip, port);

      decoder.skip (11);  // ip_server, port_server, ip_alt, dummy
    }

  return sources;
}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief Get metadata from data
//! \param data Encoded data
//! \param type Metadata type
//! \see get_cached_metas@helper_library_db.pas
//! \see get_trusted_metas@helper_library_db.pas
//! \see read_details_DB_Download@helper_download_disk.pas
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
std::map <int, mobius::bytearray>
decode_metadata (const mobius::bytearray& data)
{
  mobius::core::log log (__FILE__, __FUNCTION__);

  auto decoder = mobius::decoder::data_decoder (data);
  std::map <int, mobius::bytearray> metadata;

  while (decoder)
    {
      auto field_type = decoder.get_uint8 ();
      auto field_size = decoder.get_uint16_le ();
      auto field_data = decoder.get_bytearray_by_size (field_size);
      metadata[field_type] = field_data;
    }

  return metadata;
}

} // namespace mobius::extension::app::ares
