#!/usr/bin/env python

import os
import json
import shutil
import argparse
import shlex
import subprocess

__version__  = '0.1.0'
__config__   = '.slackpack'
__defaults__ = {
  "always_ignore": [__config__, '.git', '.DS_Store', '*.log']
}

def _parse_config(args):
  target_config = args.directory + '/' + args.config
  f = open(target_config)
  config = json.load(f)

  # Merge defaults
  config = dict(__defaults__.items() + config.items())
  config['ignore'] += config['always_ignore']

  return dict(vars(args).items() + config.items())

def _tmp_dir(config):
  tmp_dir = '{0}-{1}-{2}-{3}'.format(config['name'],
                                     config['version'],
                                     config['arch'],
                                     config['build'])
  return tmp_dir

def _copy_files_to_tmp_dir(tmp_dir, config):
  # TODO: Support nested folder patterns
  shutil.copytree(config['directory'], tmp_dir,
                  ignore=shutil.ignore_patterns(*config['ignore'])
                  )

def _prefix_files(tmp_dir, config):
  for prefix in config['prefix']:
    srcs = config['prefix'][prefix]
    dest = tmp_dir + '/' + prefix

    if not os.path.exists(dest): os.makedirs(dest)

    for src in srcs:
      full_src = tmp_dir + '/' + src
      shutil.move(full_src, dest)

def _gzip(tmp_dir):
  shutil.make_archive(tmp_dir, 'gztar', tmp_dir)
  shutil.move(tmp_dir + '.tar.gz', tmp_dir + '.tgz')

def _cleanup(tmp_dir):
  shutil.rmtree(tmp_dir)

def _run_tasks(tmp_dir, config):
  if 'tasks' in config:
    for task in config['tasks']:
      print("Running: " + task)
      subprocess.call(shlex.split(task))

def pack(args):
  config  = _parse_config(args)
  tmp_dir = _tmp_dir(config)

  if not config['version']:
    exit('You must specify a target version.')

  _run_tasks(tmp_dir, config)
  _copy_files_to_tmp_dir(tmp_dir, config)
  _prefix_files(tmp_dir, config)
  _gzip(tmp_dir)
  _cleanup(tmp_dir)

  print("Packed " + config['name'] + " " + config['version'])

def main():
  arger = argparse.ArgumentParser(description="")

  arger.add_argument('directory')

  arger.add_argument('-v', '--version', help="target version")
  arger.add_argument('-a', '--arch', help="target architecture", default="noarch")
  arger.add_argument('-b', '--build', help="target build", default="unraid")

  # Parse
  args = arger.parse_args()

  args.config = __config__
  args.directory = os.path.dirname(os.path.abspath(args.directory + '/' + args.config))

  pack(args)

if __name__ == '__main__': main()
