#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Subset eddy Dataset
"""
import logging

from py_eddy_tracker import EddyParser
from py_eddy_tracker.observations.tracking import TrackEddiesObservations

logger = logging.getLogger("pet")


def id_parser():
    parser = EddyParser("Eddy Subsetter")
    parser.add_argument("filename")
    parser.add_argument("filename_out")

    group = parser.add_argument_group("Extraction options")
    group.add_argument(
        "-p",
        "--period",
        nargs=2,
        type=int,
        help="Start day and end day, if it's negative value we will add to day min and add to day max, if 0 it s not use",
    )
    group.add_argument(
        "-l",
        "--length",
        nargs=2,
        type=int,
        help="Minimal and maximal quantity of observation for one track, ones bounds could be negative, it will be not use",
    )
    group.add_argument(
        "-f",
        "--full_path",
        action="store_true",
        help="Extract path, if one obs or more are selected",
    )
    group.add_argument(
        "-d",
        "--remove_incomplete",
        action="store_true",
        help="Extract path only if all obs are selected",
    )
    group.add_argument(
        "--reject_virtual",
        action="store_true",
        help="If there are only virtual observation in selection, we don't select track",
    )
    group.add_argument(
        "-a",
        "--area",
        nargs=4,
        type=float,
        metavar=("llcrnrlon", "llcrnrlat", "urcrnrlon", "urcrnrlat"),
        help="Coordinates of bounding to extract",
    )
    group.add_argument(
        "--direction",
        choices=["E", "W", "S", "N"],
        help="Select only track which have an end point which go in this direction",
    )
    group.add_argument(
        "--minimal_degrees_displacement_in_direction",
        type=float,
        help="Minimal displacement in direction specified in --directio options",
    )
    group.add_argument(
        "--select_first_observation_in_box",
        type=float,
        help="Select only the first obs in each box for each tracks, value specified must be resolution",
    )
    group.add_argument(
        "--remove_var", nargs="+", type=str, help="remove all listed variable"
    )
    group.add_argument(
        "--include_var",
        nargs="+",
        type=str,
        help="use only listed variable, remove_var will be ignored",
    )
    group.add_argument(
        "-i", "--ids", nargs="+", type=int, help="List of tracks which will be extract"
    )

    group = parser.add_argument_group("General options")
    group.add_argument(
        "--sort_time", action="store_true", help="sort all observation with time"
    )

    parser.add_argument(
        "-n",
        "--no_raw_mode",
        action="store_true",
        help="Uncompress all data, could be create a memory error for huge file, but is safer for extern file of py eddy tracker",
    )
    return parser


if __name__ == "__main__":
    args = id_parser().parse_args()

    # Original dataset
    dataset = TrackEddiesObservations.load_file(
        args.filename,
        raw_data=False if args.no_raw_mode else True,
        remove_vars=args.remove_var,
        include_vars=args.include_var,
    )

    # Select with id
    if args.ids is not None:
        dataset = dataset.extract_ids(args.ids)

    # Select with length
    if args.length is not None:
        dataset = dataset.extract_with_length(args.length)

    # Select with a start date and end date
    if args.period is not None:
        dataset = dataset.extract_with_period(
            args.period,
            full_path=args.full_path,
            remove_incomplete=args.remove_incomplete,
            reject_virtual=args.reject_virtual,
        )

    # Select track which go through an area
    if args.area is not None:
        area = dict(
            llcrnrlon=args.area[0],
            llcrnrlat=args.area[1],
            urcrnrlon=args.area[2],
            urcrnrlat=args.area[3],
        )
        dataset = dataset.extract_with_area(
            area,
            full_path=args.full_path,
            remove_incomplete=args.remove_incomplete,
            reject_virtual=args.reject_virtual,
        )

    # Select only track which go in the direction specified
    if args.direction:
        if args.minimal_degrees_displacement_in_direction:
            dataset = dataset.extract_in_direction(
                args.direction, value=args.minimal_degrees_displacement_in_direction
            )
        else:
            dataset = dataset.extract_in_direction(args.direction)

    if args.select_first_observation_in_box:
        dataset = dataset.extract_first_obs_in_box(
            res=args.select_first_observation_in_box
        )

    if args.sort_time:
        logger.debug("start sorting ...")
        dataset.obs.sort(order=["time", "lon", "lat"])
        logger.debug("end sorting")

    # if no data, no output will be written
    if len(dataset) == 0:
        logger.warning("No data are selected, out file couldn't be create")
    else:
        dataset.write_file(filename=args.filename_out)
