#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Subset eddy Dataset
"""
from py_eddy_tracker import EddyParser
from py_eddy_tracker.observations.tracking import TrackEddiesObservations
import logging

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)
