# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# Mobius Forensic Toolkit
# Copyright (C) 2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019 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 CLibrary
import CXMLElement
import mobius
import pymobius.p2p
import pymobius.p2p.remote_file
from pymobius.p2p.local_file import *

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief get folders from list recursively
# @param folder_list folder list
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def iter_folders (folder_list):
  for folder in folder_list:
    yield folder

    for child in iter_folders (folder.children):
      yield child

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Retrieve data from Library1.dat
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def retrieve (item, model, f, username):

  # Check file
  if not f:
    return

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

  # decode file
  decoder = mobius.decoder.mfc_decoder (reader)
  clib = CLibrary.decode (decoder)

  # process data
  for folder in iter_folders (clib.folders):

    # add files to local files list
    for clf in folder.files:
      lf = new_local_file (folder, clf)
      lf.username = username
      model.local_files.append (lf)

      # add files with known sources to the remote_files list
      for source in clf.sources:
        rf = new_remote_file (clf, source)
        rf.username = username
        model.remote_files.append (rf)

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

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Create local file from CLibraryFile
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def new_local_file (folder, clf):
  f = local_file ()
  f.app_id = 'shareaza'
  f.app = 'Shareaza'
  f.name = clf.name
  f.size = clf.size
  f.path = folder.path + '\\' + clf.name

  # flags
  f.flag_shared = STATE_YES if clf.b_shared else STATE_NO
  f.flag_completed = STATE_YES
  # @todo f.flag_downloaded = STATE_YES
  f.flag_uploaded = STATE_YES if clf.uploads_started > 0 else STATE_NO
  # @todo f.flag_corrupted

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

  # metadata
  f.add_metadata ('Last modification date/time', clf.last_modification_time)
  f.add_metadata ('Uploads started', clf.uploads_started)
  f.add_metadata ('Rating', clf.rating)
  f.add_metadata ('Comments', clf.comments)
  f.add_metadata ('Share tags', clf.share_tags)

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

 # =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Create remote file from File and Source
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def new_remote_file (f, source):
  rf = pymobius.p2p.remote_file.remote_file ()
  rf.app_id = 'shareaza'
  rf.app = 'Shareaza'
  rf.name = f.name
  rf.size = f.size
  rf.timestamp = source.timestamp
  rf.url = source.url
  
  # hashes
  rf.set_hash ('sha1', f.hash_sha1)
  rf.set_hash ('tiger', f.hash_tiger)
  rf.set_hash ('ed2k', f.hash_ed2k)
  rf.set_hash ('bth', f.hash_bth)
  rf.set_hash ('md5', f.hash_md5)
  
  # peer
  rf.peer.ip = source.ip

  # metadata
  rf.add_metadata ('Rating', f.rating)
  rf.add_metadata ('Comments', f.comments)
  rf.add_metadata ('Share Tags', f.share_tags)
  
  for name, value in CXMLElement.get_metadata_from_pxml (f.pxml):
    rf.add_metadata (name, value)

  return rf
