#!/usr/bin/env python

r"""
This is a simple script that will import a complete working subset of M4DB database records from a set of table
files (in JSON format) and a collection of zip files containing the actual model / NEB path / geometry data
held in M4DB.

@author L. Nagy, W. Williams
"""

import sys
import os

from argparse import ArgumentParser

from m4db_database.sessions import get_session

from m4db_database.import_data_files_utilities import extract_zip_to_file_root

from m4db_database.import_json_utilities import import_db_user, import_project, import_running_status
from m4db_database.import_json_utilities import import_software
from m4db_database.import_json_utilities import import_unit
from m4db_database.import_json_utilities import import_physical_constant
from m4db_database.import_json_utilities import import_size_convention
from m4db_database.import_json_utilities import import_anisotropy_form
from m4db_database.import_json_utilities import import_material
from m4db_database.import_json_utilities import import_neb_calculation_type
from m4db_database.import_json_utilities import import_geometry
from m4db_database.import_json_utilities import import_model
from m4db_database.import_json_utilities import import_neb


def verify_files(dir_path):
    r"""
    Verify that all the files required for this import exist in the 'dir_path'.
    Args:
        dir_path: the location where import files are expected to be.

    Returns:
        The name of the missing file, on success the empty string is returned.
    """

    json_files = [
        "anisotropy_form.json",
        "db_user.json",
        "geometry.json",
        "material.json",
        "model.json",
        "neb_calculation_type.json",
        "neb.json",
        "physical_constant.json",
        "size_convention.json",
        "software.json",
        "unit.json"
    ]

    zip_files = [
        "geometry.zip",
        "model.zip",
        "neb.zip"
    ]

    file_names = os.listdir(dir_path)

    # Check the JSON files
    for expected_json_file in json_files:
        if expected_json_file not in file_names:
            return expected_json_file

    # Check the ZIP files
    for expected_zip_file in zip_files:
        if expected_zip_file not in file_names:
            return expected_zip_file

    return ""


def get_command_line_parser():
    r"""
    Retrieve a command line parser object for this script.

    Returns:
        A command line parser object for this script.

    """
    parser = ArgumentParser()

    parser.add_argument("dir_path",
                        help="the directory containing the import data files.")
    parser.add_argument("-d", "--with_original_dates", action="store_true",
                        help="Flag indicating that the original dates in the JSON file should be used when importing")

    return parser


def main():
    parser = get_command_line_parser()
    args = parser.parse_args()

    print("Importing database using NEB paths...")
    missing_file = verify_files(args.dir_path)
    if missing_file != "":
        print("The file '{}' is missing from the import directory".format(missing_file))
        sys.exit(1)

    session = get_session()

    import_db_user(os.path.join(args.dir_path, "db_user.json"), session, args.with_original_dates)
    import_software(os.path.join(args.dir_path, "software.json"), session, args.with_original_dates)
    import_project(os.path.join(args.dir_path, "project.json"), session, args.with_original_dates)
    import_unit(os.path.join(args.dir_path, "unit.json"), session, args.with_original_dates)
    import_running_status(os.path.join(args.dir_path, "running_status.json"), session, args.with_original_dates)
    import_physical_constant(os.path.join(args.dir_path, "physical_constant.json"), session, args.with_original_dates)
    import_size_convention(os.path.join(args.dir_path, "size_convention.json"), session, args.with_original_dates)
    import_anisotropy_form(os.path.join(args.dir_path, "anisotropy_form.json"), session, args.with_original_dates)
    import_material(os.path.join(args.dir_path, "material.json"), session, args.with_original_dates)
    import_neb_calculation_type(os.path.join(args.dir_path, "neb_calculation_type.json"), session, args.with_original_dates)

    import_geometry(os.path.join(args.dir_path, "geometry.json"), session, args.with_original_dates)
    extract_zip_to_file_root(os.path.join(args.dir_path, "geometry.zip"))

    import_model(os.path.join(args.dir_path, "model.json"), session, args.with_original_dates)
    extract_zip_to_file_root(os.path.join(args.dir_path, "model.zip"))

    import_neb(os.path.join(args.dir_path, "neb.json"), session, args.with_original_dates)
    extract_zip_to_file_root(os.path.join(args.dir_path, "neb.zip"))

    session.close()

    print("Done!")


if __name__ == "__main__":
    main()
