#!/usr/bin/env python
from argparse import ArgumentParser, RawTextHelpFormatter as ArgFormatter
from glob import glob
from json import dumps
from os import chdir, makedirs
from os.path import basename, dirname, join, splitext
from pathlib import Path
from itsim_scripts.utils import get_project_json, get_valid_filename, layer_types


def main(sys_args):
    chdir(str(Path(__file__).resolve().parents[1]))
    default_ref_name = "Base system"
    default_ref_desc = ""
    orgas = [splitext(basename(f))[0] for f in glob(join('bootstrap_db', '*', '*.json'))]
    distance_units = ["m", "mi"]
    parser = ArgumentParser(
        description="Create a json project",
        formatter_class=ArgFormatter
    )
    parser.add_argument('-o', '--organization', metavar='name', dest='orga_name', type=str, required=True,
                        help="Organization. One amongst:\n- {}".format('\n- '.join(orgas)))
    parser.add_argument('-f', '--filename', metavar='filename_without_extension', dest='filename', type=str,
                        help="Project file name (if not specified, it will be generated from project name).\n"
                        + "Will be use for the json project filename, the project data directory and gtfs filename.")
    parser.add_argument('-n', '--name', metavar='name', dest='project_name', type=str, required=True,
                        help="Project name")
    parser.add_argument('-d', '--desc', metavar='decription', dest='desc', type=str, default="",
                        help="Project description")
    parser.add_argument('-g', '--gtfs', metavar='gtfs_file', dest='gtfs_file', type=str,
                        help="GTFS file path")
    parser.add_argument('--ref-name', metavar='name', dest='ref_name', type=str, default=default_ref_name,
                        help='Name of reference scenario.\nDefault to "{}"'.format(default_ref_name))
    parser.add_argument('--ref-desc', metavar='description', dest='ref_desc', type=str, default=default_ref_desc,
                        help='Description of reference scenario.\nDefault to "{}"'.format(default_ref_desc))
    parser.add_argument('-s', '--scenario', nargs=3, metavar=('name', 'routes', 'one_pattern_per_route'), dest='scenarios',
                        type=str, action='append',
                        help="""Add a scenario.
[name] scenario name
[routes] could be "all", "None" or a comma separated list of route ids to keep
[one_pattern_per_route] could be false/0 or true/1 to only keep one pattern per route""")
    parser.add_argument('-l', '--layer', nargs=12,
                        metavar=(
                            'type', 'tileset_id', 'tileset_name',
                            'layer_name', 'layer_unit', 'layer_value_name', 'layer_value_description', 'layer_value_unit',
                            'shape_or_json_file', 'property_from', 'property_to', 'legend',
                        ),
                        dest='layers', type=str, action='append',
                        help="""Add a layer.
[type] layer type. One of:\n- {}
[tileset_id] tileset id. mapbox_user.table_name format
[tileset_name] tileset name. ProjectName_layerType_tileset format
[layer_name] 2-letters-lang,name[2-letters-lang,name ...] format.
  Could also be "none", "pop", "emp" or "pot"
[layer_unit] 2-letters-lang,unit[2-letters-lang,unit ...] format.
  Could also be "none", "pop", "emp" or "pot"
[layer_value_name] 2-letters-lang,name[2-letters-lang,name ...] format.
  Could also be "none", "pop", "emp" or "pot"
[layer_value_description] 2-letters-lang,descr[2-letters-lang,descr ...] format.
  Could also be "none", "pop", "emp" or "pot"
[layer_value_unit] 2-letters-lang,unit[2-letters-lang,unit ...] format.
  Could also be "none", "pop", "emp" or "pot"
[shape_or_json_file] shape file path or geojson file path
[property_from] name of the property to read from the shape file.
  Could be "none"
[property_to] name of the property to use in the mapbox json.
  Could be "none"
[legend] max_value,color[,max_value,color ...] format for density layer ;
         color format for value layer ;
  with color in RRGGBB format.
  Could be "none" for non-computation layer.
""".format(
                            '\n- '.join(layer_types)
                        ))
    parser.add_argument('--param-buffer', nargs='+', metavar='mode size',
                        dest='buffers', type=int, default=[],
                        help="Buffer size by mode.\nYou have to finish with default size (no mode) or 0")
    parser.add_argument('--param-cost', nargs='+', metavar='mode cost',
                        dest='costs', type=float, default=[],
                        help="Cost per kilometer by mode.\nYou have to finish with the default_cost (no mode) or 0")
    parser.add_argument('--param-turnaround-min', metavar='minutes',
                        dest='turnaround_minimum', type=float, default=None,
                        help="Minimum turnaround in minutes.")
    parser.add_argument('--param-turnaround-pct', metavar='percentage',
                        dest='turnaround_percentage', type=float, default=None,
                        help="Turnaround in percentage (0-100).")
    parser.add_argument('--param-typical-days', nargs='+', metavar='name date',
                        dest='typical_days', type=str, required=True,
                        help="Typical days.\ndate is YYYYMMDD format")
    parser.add_argument('--param-time-types', nargs='+', metavar='name start_time end_time',
                        dest='time_types', type=str, default=[],
                        help="Time types.\ntime is HHMMSS format")
    parser.add_argument('--param-center', nargs=2, metavar=('longitude', 'latitude'),
                        dest='center', type=float, default=[],
                        help="Map center")
    parser.add_argument('--param-distance', metavar='distance_unit', dest='distance_unit',
                        type=str, choices=distance_units, required=True,
                        help="Distance unit of this project.")
    parser.add_argument('--param-currency-symbol', metavar='currency-symbol', dest='currency', type=str, required=True,
                        help="Currency symbol of this project (3 chars max)")
    args = parser.parse_args(args=sys_args)
    name_norm = args.filename if args.filename else get_valid_filename(args.project_name)
    del args.filename
    json = get_project_json(name_norm=name_norm, **vars(args))
    filename = join('bootstrap_db', get_valid_filename(args.orga_name), 'projects', name_norm + '.json')
    makedirs(dirname(filename), exist_ok=True)
    with open(filename, 'w') as f:
        f.write(dumps(json, indent=2, ensure_ascii=False))
    print("{} created".format(filename))


if __name__ == '__main__':
    from sys import argv
    main(argv[1:])
