// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Mobius Forensic Toolkit
// Copyright (C) 2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018 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 "imagefile.h"
#include "imagefile_impl_dossier.h"
#include "imagefile_impl_raw.h"
#include "imagefile_impl_solo.h"
#include "imagefile_impl_talon.h"
#include "imagefile_impl_null.h"
#include "ewf/imagefile_impl.h"
#include "msr/imagefile_impl.h"
#include "split/imagefile_impl.h"
#include <mobius/io/file.h>

namespace mobius
{
namespace imagefile
{
namespace
{
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief imagefile types available
// id, description, file extensions, writeable (true/false)
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
static const std::vector <info> IMAGEFILE_TYPES =
{
  {"dossier", "Logicube Dossier image file", "LOG", false},
  {"ewf", "EWF image file", "E01|e01|ewf", true},
  {"msr", "Samsung Secret Zone image file", "MSR|msr", false},
  {"raw", "raw image file", "raw|dd|img|*", true},
  {"solo", "ICS Solo image file", "txt", false},
  {"split", "split image file", "001", true},
  {"talon", "Logicube Talon image file", "LOG", false},
};

} // namespace

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief get list of available imagefile types
//! \return list of imagefile types
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
std::vector <info>
get_imagefile_types ()
{
  return IMAGEFILE_TYPES;
}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief construct object
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
imagefile::imagefile ()
{
  impl_ = std::make_shared <imagefile_impl_null> ();
}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief constructor from implementation pointer
//! \param impl implementation pointer
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
imagefile::imagefile (std::shared_ptr <imagefile_impl_base> impl)
  : impl_ (impl)
{
}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief check if imagefile is is_available
//! \return true/false
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
bool
imagefile::is_available () const
{
  mobius::io::file f (impl_->get_url ());
  return f && f.exists ();
}

// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//! \brief create new imagefile object
//! \param url imagefile URL
//! \param type imagefile type (default = "autodetect")
//! \return imagefile object
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
imagefile
new_imagefile_from_url (const std::string& url, const std::string& type)
{
  // detect imagefile type, if type == "autodetect"
  std::string i_type = type;

  if (type == "autodetect")
    {
      if (imagefile_impl_dossier::is_instance (url))
        i_type = "dossier";

      else if (ewf::imagefile_impl::is_instance (url))
        i_type = "ewf";

      else if (msr::imagefile_impl::is_instance (url))
        i_type = "msr";

      else if (imagefile_impl_talon::is_instance (url))
        i_type = "talon";

      else if (imagefile_impl_solo::is_instance (url))
        i_type = "solo";

      else if (split::imagefile_impl::is_instance (url))
        i_type = "split";

      else
        i_type = "raw";
    }

  // create impl according to i_type
  std::shared_ptr <imagefile_impl_base> impl;

  if (i_type == "dossier")
    impl = std::make_shared <imagefile_impl_dossier> (url);

  else if (i_type == "ewf")
    impl = std::make_shared <ewf::imagefile_impl> (url);

  else if (i_type == "msr")
    impl = std::make_shared <msr::imagefile_impl> (url);

  else if (i_type == "raw")
    impl = std::make_shared <imagefile_impl_raw> (url);

  else if (i_type == "solo")
    impl = std::make_shared <imagefile_impl_solo> (url);

  else if (i_type == "split")
    impl = std::make_shared <split::imagefile_impl> (url);

  else if (i_type == "talon")
    impl = std::make_shared <imagefile_impl_talon> (url);

  else
    impl = std::make_shared <imagefile_impl_null> ();

  return imagefile (impl);
}

} // namespace imagefile
} // namespace mobius
