# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# Mobius Forensic Toolkit
# Copyright (C) 2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020 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 CXMLElement

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Vendors
# @see Vendors.xml
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
VENDORS = {'RAZA' : 'Shareaza',
           'RAZB' : 'ShareazaBeta',
           'RZCB' : 'ShareazaPlus',
           'PEER' : 'PeerProject',
           'ACQL' : 'Acqlite',
           'ACQX' : 'Acquisition',
           'AGIO' : 'Adagio',
           'AGNT' : 'Agentella',
           'ARES' : 'Ares',
           'ATOM' : 'AtomWire',
           'BEAR' : 'BearShare',
           'CULT' : 'Cultiv8r',
           'DC++' : 'DC++',
           'ED2K' : 'eDonkey2000',
           'FOXY' : 'Foxy',
           'FUST' : 'Fusteeno',
           'GDNA' : 'GnucDNA',
           'GIFT' : 'giFT-Gnutella',
           'GNEW' : 'GNewtellium',
           'GNOT' : 'Gnotella',
           'GNTD' : 'Gtk-Gnutella',
           'GNTG' : 'Gnutelligentsia',
           'GNUC' : 'Gnucleus',
           'GNUT' : 'Gnut',
           'GNZL' : 'Gnoozle',
           'GTKG' : 'Gtk-Gnutella',
           'HSLG' : 'Hagelslag',
           'HYDR' : 'Hydranode',
           'JOET' : 'Joetella',
           'LIME' : 'LimeWire',
           'MACT' : 'Mactella',
           'MESH' : 'iMesh',
           'MLDK' : 'MLdonkey',
           'MMMM' : 'Morpheus',
           'MNAP' : 'MyNapster',
           'MOOD' : 'MoodAmp',
           'MRPH' : 'Morpheus',
           'MUTE' : 'Mutella',
           'MXIE' : 'Mxie',
           'NAPS' : 'NapShare',
           'OCFG' : 'OpenCola',
           'OPRA' : 'Opera',
           'PHEX' : 'Phex',
           'QTEL' : 'Qtella',
           'SNOW' : 'FrostWire',
           'SNUT' : 'SwapNut',
           'SWAP' : 'Swapper.NET',
           'SWFT' : 'SwiftPeer',
           'TFLS' : 'TrustyFiles',
           'TOAD' : 'ToadNode',
           'XOLO' : 'Xolox',
           'XTLA' : 'XTella',
           'ZIGA' : 'Ziga'
          }

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Generic data holder
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class dataholder (object):
  pass

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# @brief Decode CQueryHit structure
# @see QueryHit.cpp - CQueryHit::Serialize
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def decode (decoder, version):
  q = dataholder ()
  q.hash_bth = None
  q.hash_md5 = None
  q.b_collection = False
  q.pxml = None
  q.b_exact_match = False
  q.nick = None

  q.search_id = decoder.get_guid ()

  if version >= 9:
    q.protocol_id = decoder.get_dword ()
  else:
    q.protocol_id = 0

  q.client_id = decoder.get_guid ()
  q.ip = decoder.get_ipv4 ()
  q.port = decoder.get_word ()
  q.speed = decoder.get_dword ()
  q.str_speed = decoder.get_string ()
  q.vendor_code = decoder.get_string ()
  q.peer_app = VENDORS.get (q.vendor_code, q.vendor_code)
  q.tri_push = decoder.get_dword ()
  q.tri_busy = decoder.get_dword ()
  q.tri_stable = decoder.get_dword ()
  q.tri_measured = decoder.get_dword ()
  q.up_slots = decoder.get_int ()
  q.up_queue = decoder.get_int ()
  q.b_chat = decoder.get_bool ()
  q.b_browse_host = decoder.get_bool ()

  q.hash_sha1 = decoder.get_hex_string (20)
  q.hash_tiger = decoder.get_hex_string (24)
  q.hash_ed2k = decoder.get_hex_string (16)

  if version >= 13:
    q.hash_bth = decoder.get_hex_string (20)
    q.hash_md5 = decoder.get_hex_string (16)

  q.url = decoder.get_string ()
  q.name = decoder.get_string ()
  q.index = decoder.get_dword ()
  q.b_size = decoder.get_bool ()

  if version >= 10:
    q.size = decoder.get_qword ()
  else:
    q.size = decoder.get_dword ()

  q.hit_sources = decoder.get_dword ()
  q.partial = decoder.get_dword ()
  q.b_preview = decoder.get_bool ()
  q.preview = decoder.get_string ()

  if version >= 11:
    q.b_collection = decoder.get_bool ()

  q.schema_uri = decoder.get_string ()
  q.schema_plural = decoder.get_string () # unused

  if q.schema_uri:
    q.pxml = CXMLElement.decode (decoder)

  q.rating = decoder.get_int ()
  q.comments = decoder.get_string ()
  q.b_matched = decoder.get_bool ()

  if version >= 12:
    q.b_exact_match = decoder.get_bool ()

  q.b_bogus = decoder.get_bool ()
  q.b_download = decoder.get_bool ()

  if version >= 15:
    q.nick = decoder.get_string ()

  if q.hit_sources == 0 and q.url:
    q.hit_sources = 1

  return q
