""" Module that uses CMAC 2.0 to remove and correct second trip returns,
correct velocity and more. A new radar object is then created with all CMAC
2.0 products. """

import copy
import json
import sys

import netCDF4
import numpy as np
import pyart

from .cmac_processing import (
    do_my_fuzz, get_melt, get_texture, fix_phase_fields, gen_clutter_field_from_refl, beam_block)
from .config import get_cmac_values, get_field_names, get_metadata

def cmac(radar, sonde, config, geotiff=None, flip_velocity=False,
         meta_append=None, verbose=True):
    """
    Corrected Moments in Antenna Coordinates

    Parameters
    ----------
    radar : Radar
        Radar object to use in the CMAC calculation.
    sonde : Object
        Object containing all the sonde data.
    config : str
        A string pointing to dictionaries containing values for CMAC 2.0
        specific to a radar.

    Other Parameters
    ----------------
    geotiff : str
        Filepath for a geotiff, if provided, will generate a beam blockage
        gate id.
    meta_append : dict, json and None
        Value key pairs to attend to global attributes. If None,
        a default metadata will be created. The metadata can also
        be created by providing a dictionary or a json file.
    verbose : bool
        If True, this will display more statistics.

    Returns
    -------
    radar : Radar
        Radar object with new CMAC added fields.

    """
    # Retrieve values from the configuration file.
    cmac_config = get_cmac_values(config)
    field_config = get_field_names(config)
    meta_config = get_metadata(config)
    # Over write site altitude

    if 'site_alt' in cmac_config.keys():
        radar.altitude['data'][0] = cmac_config['site_alt']

    # Obtaining variables needed for fuzzy logic.

    radar_start_date = netCDF4.num2date(
        radar.time['data'][0], radar.time['units'],
        only_use_cftime_datetimes=False, only_use_python_datetimes=True)
    print('##', str(radar_start_date))

    temp_field = field_config['temperature']
    alt_field = field_config['altitude']
    vel_field = field_config['velocity']

    if 'gen_clutter_from_refl' not in cmac_config.keys():
        cmac_config['gen_clutter_from_refl'] = False

    if cmac_config['gen_clutter_from_refl']:
        new_clutter_field = gen_clutter_field_from_refl(radar, field_config['input_clutter_corrected_reflectivity'],
                                                        field_config['reflectivity'],
                                                        diff_dbz=cmac_config['gen_clutter_from_refl_diff'],
                                                        max_h=cmac_config['gen_clutter_from_refl_alt'])
        radar.add_field(field_config['clutter'], new_clutter_field, replace_existing=True)
        radar.fields[field_config['clutter']]['units'] = '1'
    # ZDR offsets
    if 'zdr_offset' in cmac_config.keys():
        if 'offset_zdrs' in cmac_config.keys():
            for fld in cmac_config['offset_zdrs']:
                radar.fields[fld]['data'] += cmac_config['zdr_offset']
        else:
            radar.fields[field_config['input_zdr']]['data'] += cmac_config['zdr_offset']


    # flipping phidp
    if 'flip_phidp' not in cmac_config.keys():
        cmac_config['flip_phidp'] = False

    if cmac_config['flip_phidp']:
        if 'phidp_flipped' in cmac_config.keys(): # user specifies fields to flip
            for fld in cmac_config['phidp_flipped']:
                radar.fields[fld]['data'] = radar.fields[fld]['data'] * -1.0
        else:  # just flip defined phidp field
            radar.fields[field_config['input_phidp_field']]['data'] = radar.fields[field_config['input_phidp_field']]['data']*-1.0

    if flip_velocity:
        radar.fields[vel_field]['data'] = radar.fields[
            vel_field]['data'] * -1.0
    z_dict, temp_dict = pyart.retrieve.map_profile_to_gates(
        sonde.variables[temp_field][:], sonde.variables[alt_field][:], radar)

    if 'clutter_mask_z_for_texture' not in cmac_config.keys():
        cmac_config['clutter_mask_z_for_texture'] = False

    if cmac_config['clutter_mask_z_for_texture']:
        masked_vr = copy.deepcopy(radar.fields[vel_field])
        if 'ground_clutter' in radar.fields.keys():
            masked_vr['data'] = np.ma.masked_where(radar.fields['ground_clutter']['data'] == 1, masked_vr['data'])
            masked_vr['data'][radar.fields['ground_clutter']['data'] == 1] = np.nan
        radar.add_field('clutter_masked_velocity', masked_vr, replace_existing=True)

        texture = get_texture(radar, 'clutter_masked_velocity')
        texture['data'][np.isnan(texture['data'])] = 0.0
    else:
        texture = get_texture(radar, vel_field)

    snr = pyart.retrieve.calculate_snr_from_reflectivity(radar)

    if not verbose:
        print('## Adding radar fields...')

    if verbose:
        print('##')
        print('## These radar fields are being added:')
    temp_dict['units'] = 'deg_C'
    z_dict['units'] = 'm'
    radar.add_field('sounding_temperature', temp_dict, replace_existing=True)
    radar.add_field('height', z_dict, replace_existing=True)
    radar.add_field('signal_to_noise_ratio', snr, replace_existing=True)
    radar.add_field('velocity_texture', texture, replace_existing=True)
    if verbose:
        print('##    sounding_temperature')
        print('##    height')
        print('##    signal_to_noise_ratio')
        print('##    velocity_texture')

    # Performing fuzzy logic to obtain the gate ids.
    rhv_field = field_config['cross_correlation_ratio']
    ncp_field = field_config['normalized_coherent_power']

    if 'mbfs' not in cmac_config: