#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Utility module to set initial data into the Configuration Database."""
import argparse
import json
import os
import shutil
from os import listdir
from os.path import dirname, join

import sip_config_db
from sip_config_db import ConfigDb, LOG, __version__
from sip_config_db.scheduling import SubarrayList, workflow_definitions
from sip_config_db.states import SDPState, ServiceState
from sip_logging import init_logger

DB = ConfigDb()


def initialise_states(data_dir: str):
    """Initialise fields for the state of SDP."""
    LOG.info('* Initialising SDP state')
    SDPState()
    with open(join(data_dir, 'services.json'), 'r') as file:
        services = json.load(file)
        for service in services['services']:
            LOG.info('* Initialising service state: %s', service)
            subsystem, name, version = service.split(':')
            ServiceState(subsystem, name, version)


def initialise_subarrays():
    """Initialise subarrays."""
    LOG.info('* Initialising subarrays')
    SubarrayList()


def add_workflow_definitions(workflows_dir: str):
    """Add workflow definitions.

    Args:
        workflows_dir (str): Path used to store workflow definitions
    """
    workflow_files = [join(workflows_dir, fn)
                      for fn in listdir(workflows_dir)
                      if fn.endswith('.json')
                      and not fn.startswith('test')
                      and not fn == 'services.json']
    for file_path in workflow_files:
        LOG.info('* Loading workflow template: %s', file_path)
        with open(file_path, 'r') as file:
            workflow_dict = json.load(file)
            workflow_definitions.add(workflow_dict, join(workflows_dir,
                                                         'templates'))


def init_db(data_dir):
    """Initialise the database.

    If specified by the first command line argument, a data path containing
    service and workflow definitions is used to initialise the database
    instead of the default data path installed as part of the config_db
    library.

    A data path should be a directory containing the following:

        - services.json  (a file defining the set of services registered with
                          the MC)
        - workflows/     (a directory of SIP workflow definitions)

    """
    DB.flush_db()
    initialise_subarrays()
    initialise_states(data_dir)
    add_workflow_definitions(join(data_dir, 'workflows'))


def main():
    """Initialise the database.

    If specified by the first command line argument, a data path containing
    service and workflow definitions is used to initialise the database
    instead of the default data path installed as part of the config_db
    library.

    A data path should be a directory containing the following:

        - services.json  (a file defining the set of services registered with
                          the MC)
        - workflows/     (a directory of SIP workflow definitions)

    """
    parser = argparse.ArgumentParser(description='Initialise the database.')
    parser.add_argument('--clear', required=False, action='store_true',
                        help='Clear the database. USE WITH CARE!')
    parser.add_argument('--data-dir', default=None, type=str, required=False,
                        help='Data dir to use. If does not exist, create.')
    parser.add_argument('--version', default=False, action='store_true',
                        help='Return the config db api version.')

    args = parser.parse_args()

    if args.version:
        print(__version__)
    elif args.clear:
        DB.flush_db()
    else:
        default_data_dir = join(dirname(sip_config_db.__file__), 'data')
        if args.data_dir is None:
            data_dir = default_data_dir
            LOG.info('Using default data path: %s', data_dir)
            init_db(data_dir)
        else:
            data_dir = os.path.abspath(args.data_dir)
            if not os.path.isdir(data_dir):
                LOG.info('Creating default data path: %s', data_dir)
                shutil.copytree(src=default_data_dir, dst=data_dir)
            else:
                LOG.info('Using user specified data path: %s', data_dir)
                init_db(data_dir)


if __name__ == '__main__':
    init_logger()
    main()
