#!/usr/bin/env python

from argparse import ArgumentParser
import json
import os

from pijon import Pijon


def parse_args():
    parser = ArgumentParser()
    subparsers = parser.add_subparsers(dest='command')
    parser.add_argument(
        '-d', '--directory', type=str, default='migrations/',
        help="Migrations' folder"
    )

    # New migration
    sub = subparsers.add_parser('new', help='Create a migration file')
    sub.add_argument('name', type=str, nargs='+', help='Migration name')

    # Migrate
    sub = subparsers.add_parser('migrate', help='Migrate')
    sub.add_argument('input', type=str, help='JSON file to migrate')
    sub.add_argument('output', type=str, help='JSON file to write')
    sub.add_argument('-t', '--target', type=str, help='Target migration')

    # List migrations
    sub = subparsers.add_parser('list', help='List migrations')
    sub.add_argument('-f', '--file', type=str, help='Compare to your JSON file')

    return parser, parser.parse_args()


class PijonScript(object):

    def __init__(self, args):
        self.args = args
        self.pijon = Pijon(folder=args.directory)

    @classmethod
    def execute(cls, args):
        script = cls(args)
        getattr(script, args.command)()

    def new(self):
        """
        Create a new migration
        """
        filename = '{0:04d}_{name}.py'.format(
            self.pijon.last_migration + 1,
            name='_'.join(self.args.name)
        )

        with open(os.path.join(self.pijon.folder, filename), 'w') as f:
            f.write((
                'import logging\n\n\n'
                'log = logging.getLogger(__name__)\n\n\n'
                'def migrate(data):\n'
                '    return data\n'
            ))

        print("File '{}' created".format(filename))

    def migrate(self):
        """
        Migrate everything or to the targeted migration
        """
        target = self.args.target
        if target and target not in self.pijon.migrations.keys():
            print('Unknown migration {}'.format(target))
            return

        # Read file
        with open(self.args.input, 'r') as f:
            input_data = json.loads(f.read())

        # Migrate in-place
        self.pijon.migrate(
            input_data,
            in_place=True,
            target=int(target) if target else None
        )

        # Write to file
        with open(self.args.output, 'w') as f:
            f.write(json.dumps(input_data, sort_keys=True, indent=4) + '\n')

    def list(self):
        """
        List available migrations
        """
        version = 0
        if self.args.file:
            with open(self.args.file, 'r') as f:
                version = json.loads(f.read()).get('version')
            if not version:
                print('* JSON file not yet migrated')
        for ident, migration in self.pijon.migrations.items():
            print('{}{} - {}'.format(
                '* ' if int(ident) == version else '',
                ident,
                migration.name
            ))


def main():
    parser, args = parse_args()
    if not args.command:
        print(parser.format_help())
        return
    PijonScript.execute(args)


if __name__ == '__main__':
    main()
