#!/usr/bin/env python

import warnings
from netCDF4 import num2date
from mpi4py import MPI
from .nc_projections import *


def create_nes(comm=None, info=False, projection=None, parallel_method='Y', balanced=False, 
               strlen=75, times=None, **kwargs):
    
    if comm is None:
        comm = MPI.COMM_WORLD
    else:
        comm = comm

    # Create time array
    if times is None:
        units = 'days since 1996-12-31 00:00:00'
        calendar = 'standard'
        times = num2date([0], units=units, calendar=calendar)
        times = [aux.replace(second=0, microsecond=0) for aux in times]
    else:
        if not isinstance(times, list):
            times = times.tolist()

    # Check if the parameters that are required to create the object have been defined in kwargs
    kwargs_list = []
    for name, value in kwargs.items():
        kwargs_list.append(name)

    if projection is None:
        required_vars = ['lat', 'lon']
    elif projection == 'regular':
        required_vars = ['lat_orig', 'lon_orig', 'inc_lat', 'inc_lon', 'n_lat', 'n_lon']
    elif projection == 'rotated':
        required_vars = ['centre_lat', 'centre_lon', 'west_boundary', 'south_boundary', 'inc_rlat', 'inc_rlon']
    elif projection == 'lcc':
        required_vars = ['lat_1', 'lat_2', 'lon_0', 'lat_0', 'nx', 'ny', 'inc_x', 'inc_y', 'x_0', 'y_0']
    elif projection == 'mercator':
        required_vars = ['lat_ts', 'lon_0', 'nx', 'ny', 'inc_x', 'inc_y', 'x_0', 'y_0']
    else:
        raise ValueError("Unknown projection: {0}".format(projection))

    for var in required_vars:
        if var not in kwargs_list:
            msg = 'WARNING!!! '
            msg += 'Variable {0} has not been defined.'.format(var)
            warnings.warn(msg)

    if projection is None:
        if parallel_method != 'X':
            raise ValueError("Parallel method must be 'X' to create points NES.")
        nessy = PointsNes(comm=comm, dataset=None, xarray=None, info=info, parallel_method=parallel_method,
                          avoid_first_hours=0, avoid_last_hours=0, first_level=0, last_level=None, balanced=balanced,
                          create_nes=True, strlen=75, times=times, **kwargs)
    elif projection == 'regular':
        nessy = LatLonNes(comm=comm, dataset=None, xarray=None, info=info, parallel_method=parallel_method,
                          avoid_first_hours=0, avoid_last_hours=0, first_level=0, last_level=None, balanced=balanced,
                          create_nes=True, times=times, **kwargs)
    elif projection == 'rotated':
        nessy = RotatedNes(comm=comm, dataset=None, xarray=None, info=info, parallel_method=parallel_method,
                           avoid_first_hours=0, avoid_last_hours=0, first_level=0, last_level=None, balanced=balanced,
                           create_nes=True, times=times, **kwargs)
    elif projection == 'lcc':
        nessy = LCCNes(comm=comm, dataset=None, xarray=None, info=info, parallel_method=parallel_method,
                       avoid_first_hours=0, avoid_last_hours=0, first_level=0, last_level=None, balanced=balanced,
                       create_nes=True, times=times, **kwargs)
    elif projection == 'mercator':
        nessy = MercatorNes(comm=comm, dataset=None, xarray=None, info=info, parallel_method=parallel_method,
                            avoid_first_hours=0, avoid_last_hours=0, first_level=0, last_level=None, balanced=balanced,
                            create_nes=True, times=times, **kwargs)
    else:
        raise NotImplementedError(projection)
    
    return nessy
    