# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 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/>.
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
import traceback
import mobius
import pymobius.p2p
import pymobius.p2p.remote_file
from pymobius.p2p.local_file import *
from . import CDownload
from . import CXMLElement

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Retrieve data
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def retrieve (item, data, f, username):
  try:
    return retrieve_file (item, data, f, username) 
  except Exception as e:
    mobius.core.logf ('WRN %s %s' % (str (e), traceback.format_exc ()))

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Retrieve data from *.sd download control file
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def retrieve_file (item, data, f, username):

  # try to open file
  if not f:
    return

  reader = f.new_reader ()
  if not reader:
    return

  # decode file
  decoder = mobius.decoder.mfc (reader)
  dlf = CDownload.decode (decoder)

  if not dlf:
    return

  # create local file
  lf = new_local_file (dlf)
  lf.username = username
  data.local_files.append (lf)

  # add file + sources to remote files
  for source in dlf.sources:
    rf = new_remote_file (dlf, source)
    rf.username = username
    data.remote_files.append (rf)

  # set file handled
  pymobius.p2p.set_handled (item, f)

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Create local file from CDownload file
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def new_local_file (dlf):
  f = local_file ()
  f.app_id = 'shareaza'
  f.app = 'Shareaza'
  f.size = dlf.size
  f.name = dlf.name
  f.path = dlf.path

  # flags
  f.flag_shared = STATE_YES if dlf.b_shared else STATE_NO
  f.flag_completed = (dlf.bytes_to_download == 0)
  f.flag_downloaded = STATE_YES if dlf.bytes_to_download < dlf.size else STATE_NO
  # @todo f.flag_uploaded
  # @todo f.flag_corrupted

  # hashes
  f.set_hash ('bth', dlf.hash_bth)
  f.set_hash ('ed2k', dlf.hash_ed2k)
  f.set_hash ('md5', dlf.hash_md5)
  f.set_hash ('sha1', dlf.hash_sha1)
  f.set_hash ('tiger', dlf.hash_tiger)

  # calculate bytes downloaded/to download
  bytes_downloaded = dlf.size - dlf.bytes_to_download
  bytes_to_download = dlf.bytes_to_download

  if dlf.size:
    bytes_downloaded = '%d (%.2f%%)' % (bytes_downloaded, float (bytes_downloaded) * 100.0 / float (dlf.size))
    bytes_to_download = '%d (%.2f%%)' % (bytes_to_download, float (bytes_to_download) * 100.0 / float (dlf.size))

  # metadata
  f.add_metadata ('Bytes downloaded', bytes_downloaded)
  f.add_metadata ('Bytes to download', bytes_to_download)

  for name, value in CXMLElement.get_metadata_from_pxml (dlf.pxml):
    f.add_metadata (name, value)

  return f

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Create remote file from local_file and source
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def new_remote_file (dlf, source):
  f = pymobius.p2p.remote_file.remote_file ()
  f.app_id = 'shareaza'
  f.app = 'Shareaza'
  f.name = dlf.name
  f.size = dlf.size
  f.timestamp = source.last_seen_time
  f.url = source.url

  # hashes
  f.set_hash ('sha1', dlf.hash_sha1)
  f.set_hash ('tiger', dlf.hash_tiger)
  f.set_hash ('ed2k', dlf.hash_ed2k)
  f.set_hash ('bth', dlf.hash_bth)
  f.set_hash ('md5', dlf.hash_md5)

  # peer
  f.peer.ip = source.ip or source.server_ip
  f.peer.port = source.port
  f.peer.nickname = source.nick
  f.peer.country_code = source.country_code
  f.peer.country = source.country_name

  # metadata
  for name, value in CXMLElement.get_metadata_from_pxml (dlf.pxml):
    f.add_metadata (name, value)

  return f
