# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 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/>.
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
import mobius
import os.path
import os
import inspect
import datetime

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
# @brief disk for item cache
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
DISK_CACHE = {}

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
# @brief generic dataholder
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
class dataholder (object):
  pass

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
# @brief get disk from datasource
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def get_disk_from_datasource (datasource):

  # get datasource key
  if not datasource:
    return None

  elif datasource.typename == 'imagefile':
    key = 'imagefile.%s' % datasource.uri

  elif datasource.typename == 'physical-device':
    key = 'device.%s' % datasource.uid

  else:
    return None

  # check disk cache
  disk = DISK_CACHE.get (key)
  
  # create new disk from datasource
  if not disk:
    
    if datasource.typename == 'imagefile':
      disk = mobius.disk.new_disk_from_url (datasource.uri)
      
    elif datasource.typename == 'physical-device':
      disk = mobius.disk.new_disk_from_device_uid (datasource.uid)

    if disk:
      DISK_CACHE[key] = disk

  # return disk
  return disk

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
# @brief get item data path
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def get_item_data_path (item, *args):
  path = os.path.join (item.case.base_folder, 'data', '%04d' % item.uid, *args)
  return path

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
# @brief create item data path
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def create_item_data_path (item, *args):
  path = os.path.join (item.case.base_folder, 'data', '%04d' % item.uid, *args)
  dirpath = os.path.dirname (path)
  
  if not os.path.exists (dirpath):
    os.makedirs (dirpath)

  return path

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
# @brief get case path
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def get_case_path (case, *args):
  path = os.path.join (case.base_folder, *args)
  return path

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
# @brief create case path
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def create_case_path (case, *args):
  path = os.path.join (case.base_folder, *args)
  dirpath = os.path.dirname (path)
  
  if not os.path.exists (dirpath):
    os.makedirs (dirpath)

  return path

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 
# @brief create plain object from python API object
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
def copy_object (value):

  if isinstance (value, list):
    value = [ copy_object (o) for o in value ]

  elif isinstance (value, (int, bool, long, str, datetime.datetime)):
    pass

  else:
    new_obj = dataholder ()

    for name, v in inspect.getmembers (value):
      if not callable (v) and not name.startswith ('__'):
        setattr (new_obj, name, copy_object (v))
        
    value = new_obj
  
  return value
