import argparse
import maps.wikimap.mapspro.services.mrc.eye.experiments.speed_limits.pylibs.road_graph_utils as rg_utils
from maps.wikimap.mapspro.services.mrc.eye.experiments.speed_limits.make_maneuvers.maneuvers_markup import ManeuversWorkerConditions, ManeuversWorkerSigns, find_diff_maneuvers, save_maneuvers


def main():
    '''
        Скрипт принимает на вход дамп графа НК содержащий вершины, ребра, условия дорожного движения (возможно)
        и знаки привязанные к ребрам (возможно) и генерирует маневры в виде словаря, где ключом выступает id вершины
        а в качестве значения набор:
            1. edge_in - входное ребро (id + флаг forward направления прохождения ребра),
            2. edge_out - выходное ребро,

        в случае генерации по условиям дорожного движения (--markup-type=by_conds)
            3. valid - допустимость манёвра с точки зрения наложенных условий

        в случае генерации по знакам (--markup-type=by_objects)
            3. valid - допустимость манёвра с точки зрения знаков

        в случае генерации различий манёвров по условиям и знакам (--markup-type=diff)
            3. valid_cond - допустимость манёвра с точки зрения наложенных условий дорожного движения
            4. valid_sign - допустимость манёвра с точки зрения знаков
            5. cond_id - id условия дорожного движения запрещающего манёвр (если valid_cond = false)
            6. sign_id - id знака запрещающего манёвр (если valid_sign = false)
        в последнем случае сохраняются только манёвры у которых valid_cond != valid_sign
    '''
    parser = argparse.ArgumentParser(description="Make maneuver markup")

    parser.add_argument('--road-graph', required=True,
                        help='Path to input json file with road graph')
    parser.add_argument('--output', default=None,
                        help='Path to output json file with maneuvers')
    parser.add_argument('--markup-type', required=True, choices=["by_conds", "by_objects", "diff"],
                        help='Type of maneuver markup ("by_conds", "by_objects, "diff")')
    parser.add_argument('--filter-min-fc', default=None, type=int,
                        help='Remove edges with FC great or equal than this value (default: None)')
    parser.add_argument('--filter-min-date', default=None,
                        help='Remove objects with date less than this value (default: None)')

    args = parser.parse_args()
    nodes, edges, objects, conds = rg_utils.load_road_graph(args.road_graph)

    if args.filter_min_fc is not None:
        edges = rg_utils.filter_edges_by_fc(edges, args.filter_min_fc)
        objects = rg_utils.remove_objects_wo_edges(objects, edges)

    if args.filter_min_date is not None:
        date = rg_utils.convertSQLDateTimeToTimestamp(args.filter_min_date)
        objects = rg_utils.remove_objects_by_date(objects, date)

    edges = rg_utils.rest_only_valid_signs_at_edge(edges, [obj["id"] for obj in objects])

    if args.markup_type == "diff":
        cond_worker = ManeuversWorkerConditions(nodes, edges, conds)
        sign_worker = ManeuversWorkerSigns(nodes, edges, objects)
        maneuvers = find_diff_maneuvers(cond_worker.maneuvers, sign_worker.maneuvers)
    else:
        worker = None
        if args.markup_type == "by_conds":
            worker = ManeuversWorkerConditions(nodes, edges, conds)
        elif args.markup_type == "by_objects":
            worker = ManeuversWorkerSigns(nodes, edges, objects)

        if worker is None:
            print("Unable to found worker for markup type: ",  args.markup_type)
            return
        maneuvers = worker.maneuvers

    if args.output is not None:
        save_maneuvers(maneuvers, args.output)


if __name__ == '__main__':
    main()
