#
# OMNIVORE CONFIDENTIAL
# __________________
#
#  [2013] - [2016] Omnivore Technologies
#  All Rights Reserved.
#
# NOTICE:  All information contained herein is, and remains
# the property of Omnivore Technologies and its suppliers,
# if any.  The intellectual and technical concepts contained
# herein are proprietary to Omnivore Technologies
# and its suppliers and may be covered by U.S. and Foreign Patents,
# patents in process, and are protected by trade secret or copyright law.
# Dissemination of this information or reproduction of this material
# is strictly forbidden unless prior written permission is obtained
# from Omnivore Technologies.
#

import argparse
import logging
import sys

from sqlalchemy import create_engine

from positronics_agent.v1_0.cache.dialects import SqliteDialect, MySqlDialect
from positronics_agent.v1_0.cache.schema_builder import SimpleSchemaBuilder
from positronics_agent.v1_0.models.mapper.schemas import cache, stores, ticket_close_candidates, scheduled_tasks

logging.basicConfig()


def make_parser():
    result = argparse.ArgumentParser()

    result.add_argument(
        'schema',
        metavar='SCHEMA',
        help='Name of schema to create',
        choices=['cache', 'stores', 'ticket_close_candidates', 'scheduled_tasks'],
    )

    result.add_argument(
        '-d', '--dialect',
        help='The dialect to use: [mysql|sqlite]',
        default='mysql',
        choices=['mysql', 'sqlite'],
    )

    result.add_argument(
        '-c', '--conn-string',
        help='Connection string for the database to migrate',
        default=None,
    )

    log_level_group = result.add_mutually_exclusive_group()
    log_level_group.add_argument("--verbose", "-v",
                                 action="store_const", dest="log_level",
                                 const=logging.INFO, default=None)
    log_level_group.add_argument("--debug", "-vv",
                                 action="store_const", dest="log_level",
                                 const=logging.DEBUG)
    log_level_group.add_argument("--quiet", "-q",
                                 action="store_const", dest="log_level",
                                 const=logging.CRITICAL)

    result.add_argument("--drop-schema", action="store_true")

    return result


def parse_args():
    all_args = sys.argv[1:]
    parser = make_parser()
    args = parser.parse_args(all_args)

    schema_mapping = {
        "cache": cache,
        "stores": stores,
        "ticket_close_candidates": ticket_close_candidates,
        "scheduled_tasks": scheduled_tasks,
    }

    schema = schema_mapping[args.schema]
    dialect = MySqlDialect() if args.dialect == "mysql" else SqliteDialect()

    return args.log_level, args.conn_string, schema, dialect, args.drop_schema


def main():
    log_level, connection_string, schema, dialect, drop_schema = parse_args()
    if log_level is not None:
        logging.getLogger('sqlalchemy.engine').setLevel(log_level)

    builder = SimpleSchemaBuilder(dialect)
    engine = create_engine(
        connection_string,
        echo=True,
        convert_unicode=True,
        **dialect.get_engine_kwargs()
    )
    builder.build_schema(schema)

    if drop_schema:
        schema.metadata.drop_all(engine, checkfirst=True)
    else:
        schema.metadata.create_all(engine, checkfirst=True)


if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        print(e.message)
