// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Mobius Forensic Toolkit
// Copyright (C) 2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021,2022 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 "item.h"
#include "profile.h"
#include <mobius/exception.inc>
#include <stdexcept>

namespace mobius
{
namespace model
{
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief Create new profile
//! \param app_id Application ID
//! \param path Path
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
profile
item::new_profile (
  const std::string& app_id,
  const std::string& path)
{
  // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  // get application UID
  // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  auto db = get_database ();

  auto stmt = db.new_statement (
                "SELECT uid "
                  "FROM application "
                 "WHERE id = ?");

  stmt.bind (1, app_id);

  if (!stmt.fetch_row ())
    throw std::runtime_error (MOBIUS_EXCEPTION_MSG ("Invalid app_id"));

  auto app_uid = stmt.get_column_int64 (0);

  // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  // Check if profile already exists
  // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  stmt = db.new_statement (
                  "SELECT uid "
                    "FROM profile "
                   "WHERE item_uid = ? "
                     "AND path = ? "
                     "AND application_uid = ?");

  stmt.bind (1, get_uid ());
  stmt.bind (2, path);
  stmt.bind (3, app_uid);

  if (stmt.fetch_row ())
    {
      auto uid = stmt.get_column_int64 (0);
      return profile (*this, uid);
    }

  // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  // create profile
  // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  stmt = db.new_statement (
                "INSERT INTO profile "
                     "VALUES (NULL, ?, NULL, ?, NULL, NULL, ?)");

  stmt.bind (1, get_uid ());
  stmt.bind (2, path);
  stmt.bind (3, app_uid);
  stmt.execute ();

  auto uid = db.get_last_insert_row_id ();
  return profile (*this, uid);
}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief Get profiles
//! \return Pprofiles
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
std::vector <profile>
item::get_profiles () const
{
  auto db = get_database ();

  auto stmt = db.new_statement (
                "SELECT uid "
                  "FROM profile "
                 "WHERE item_uid = ?");

  stmt.bind (1, get_uid ());

  std::vector <profile> profiles;

  while (stmt.fetch_row ())
    {
      auto uid = stmt.get_column_int64 (0);
      profiles.emplace_back (*this, uid);
    }

  return profiles;
}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief Remove profiles by application ID
//! \param app_id Application ID
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void
item::remove_profiles_by_app_id (const std::string& app_id)
{
  // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  // get application UID
  // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  auto db = get_database ();

  auto stmt = db.new_statement (
                "SELECT uid "
                  "FROM application "
                 "WHERE id = ?");

  stmt.bind (1, app_id);

  if (!stmt.fetch_row ())
    throw std::runtime_error (MOBIUS_EXCEPTION_MSG ("Invalid app_id"));

  auto app_uid = stmt.get_column_int64 (0);

  // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  // delete profiles
  // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  stmt = db.new_statement (
                "DELETE FROM profile "
                      "WHERE item_uid = ? "
                        "AND application_uid = ?");

  stmt.bind (1, get_uid ());
  stmt.bind (2, app_uid);
  stmt.execute ();
}

} // namespace model
} // namespace mobius
