#
# OMNIVORE CONFIDENTIAL
# __________________
#
#  [2013] - [2024] 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.factory import SharedCacheFactory, SeparateCacheFactory, auto_db_schema_factory
from positronics_agent.v1_0.cache.schema_builder import SimpleSchemaBuilder, SharedSchemaBuilder
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]

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


def main():
    log_level, connection_string, schema, dialect, drop_schema = parse_args()

    dialect_obj = MySqlDialect() if dialect == "mysql" else SqliteDialect()
    builder_cls = SharedSchemaBuilder if dialect == "mysql" else SimpleSchemaBuilder
    cache_factory_cls = auto_db_schema_factory(SharedCacheFactory if dialect == "mysql" else SeparateCacheFactory)

    if log_level is not None:
        logging.getLogger('sqlalchemy.engine').setLevel(log_level)

    builder = builder_cls(dialect_obj)
    builder.build_schema(schema)

    cache_factory = cache_factory_cls(schema, connection_string, dialect_obj, 'test-store1')
    if drop_schema:
        schema.metadata.drop_all(cache_factory.engine, checkfirst=True)
    else:
        _ = cache_factory.engine


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