#!/usr/bin/env python2.7

import sys
import os

_APP_PATH = \
    os.path.join(os.path.dirname(__file__), '..', '..', '..')

sys.path.insert(0, os.path.abspath(_APP_PATH))

import logging
import argparse
import re

import pm.config.log
import pm.manifest

_LOGGER = logging.getLogger(__name__)

def _parse_args():
    description = "Create an archive with all differences since the manifest was written."
    parser = argparse.ArgumentParser(description=description)
    parser.add_argument(
        'root_path',
        help='Root path')

    parser.add_argument(
        'patch_name',
        help='Patch name')

    parser.add_argument(
        'output_path',
        help='Output path')

    parser.add_argument(
        '-mf', '--manifest-filename',
        help='Manifest filename')

    parser.add_argument(
        '-e', '--exclude-rel-path',
        metavar='REL-PATH',
        action='append',
        dest='excluded_rel_paths',
        help="Ignore the contents of this child path")

    parser.add_argument(
        '-i', '--include-rel-path',
        metavar='REL-PATH',
        action='append',
        dest='included_rel_paths',
        help="Constraint the matched files to one or more directories")

    parser.add_argument(
        '-j', '--json',
        action='store_true',
        help="Print result in JSON")

    args = parser.parse_args()

    return args

def _main():
    args = _parse_args()

    root_path = args.root_path
    manifest_filename = args.manifest_filename
    excluded_rel_paths = args.excluded_rel_paths or []
    included_rel_paths = args.included_rel_paths or []
    patch_name = args.patch_name
    patch_output_path = args.output_path
    do_print_json = args.json

    if re.match(pm.config.patch.NAME_RX, patch_name) is None:
        print("The patch-name can only have numbers, letters, and "
              "underscores.")

        sys.exit(1)

    m = pm.manifest.Manifest(
            root_path, 
            manifest_filename=manifest_filename, 
            excluded_rel_paths=excluded_rel_paths,
            included_rel_paths=included_rel_paths)

    result = None

    try:
        patch_filepath = m.make_patch(patch_name, patch_output_path)
    except pm.manifest.NoChangedFilesException:
        if do_print_json is True:
            result = {
                'found_changes': False,
            }
        else:
            print("No files have been changed.")
    else:
        if do_print_json is True:
            result = {
                'found_changes': True,
                'patch_filepath': patch_filepath,
            }
        else:
            print("Patch file-path:")
            print('')
            print(patch_filepath)

    if do_print_json is True:
        print(pm.utility.pretty_json_dumps(result))
    else:
        print('')

if __name__ == '__main__':
    pm.config.log.configure_log()
    _main()
