import numpy as np
import pandas as pd
from pvlib.iotools import tmy
from pvlib._deprecation import pvlibDeprecationWarning
from ..conftest import DATA_DIR
import pytest
import warnings

# test the API works
from pvlib.iotools import read_tmy3

TMY2_TESTFILE = DATA_DIR / '12839.tm2'
# TMY3 format (two files below) represents midnight as 24:00
TMY3_TESTFILE = DATA_DIR / '703165TY.csv'
TMY3_FEB_LEAPYEAR = DATA_DIR / '723170TYA.CSV'
# The SolarAnywhere TMY3 format (file below) represents midnight as 00:00
TMY3_SOLARANYWHERE = DATA_DIR / 'Burlington, United States SolarAnywhere Time Series 2021 Lat_44_465 Lon_-73_205 TMY3 format.csv'  # noqa: E501


def test_read_tmy3():
    tmy.read_tmy3(TMY3_TESTFILE, map_variables=False)


def test_read_tmy3_recolumn():
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        data, meta = tmy.read_tmy3(TMY3_TESTFILE, recolumn=True)
    assert 'GHISource' in data.columns


def test_read_tmy3_norecolumn():
    data, _ = tmy.read_tmy3(TMY3_TESTFILE, map_variables=False)
    assert 'GHI source' in data.columns


def test_read_tmy3_raise_valueerror():
    with pytest.raises(ValueError, match='`map_variables` and `recolumn`'):
        _ = tmy.read_tmy3(TMY3_TESTFILE, recolumn=True, map_variables=True)


def test_read_tmy3_map_variables():
    data, meta = tmy.read_tmy3(TMY3_TESTFILE, map_variables=True)
    assert 'ghi' in data.columns
    assert 'dni' in data.columns
    assert 'dhi' in data.columns
    assert 'pressure' in data.columns
    assert 'wind_direction' in data.columns
    assert 'wind_speed' in data.columns
    assert 'temp_air' in data.columns
    assert 'temp_dew' in data.columns
    assert 'relative_humidity' in data.columns
    assert 'albedo' in data.columns
    assert 'ghi_extra' in data.columns
    assert 'dni_extra' in data.columns
    assert 'precipitable_water' in data.columns


def test_read_tmy3_map_variables_deprecating_warning():
    with pytest.warns(pvlibDeprecationWarning, match='names will be renamed'):
        data, meta = tmy.read_tmy3(TMY3_TESTFILE)


def test_read_tmy3_coerce_year():
    coerce_year = 1987
    data, _ = tmy.read_tmy3(TMY3_TESTFILE, coerce_year=coerce_year,
                            map_variables=False)
    assert (data.index[:-1].year == 1987).all()
    assert data.index[-1].year == 1988


def test_read_tmy3_no_coerce_year():
    coerce_year = None
    data, _ = tmy.read_tmy3(TMY3_TESTFILE, coerce_year=coerce_year,
                            map_variables=False)
    assert 1997 and 1999 in data.index.year
    assert data.index[-2] == pd.Timestamp('1998-12-31 23:00:00-09:00')
    assert data.index[-1] == pd.Timestamp('1999-01-01 00:00:00-09:00')


def test_read_tmy2():
    tmy.read_tmy2(TMY2_TESTFILE)


def test_gh865_read_tmy3_feb_leapyear_hr24():
    """correctly parse the 24th hour if the tmy3 file has a leap year in feb"""
    data, meta = read_tmy3(TMY3_FEB_LEAPYEAR, map_variables=False)
    # just to be safe, make sure this _IS_ the Greensboro file
    greensboro = {
        'USAF': 723170,
        'Name': '"GREENSBORO PIEDMONT TRIAD INT"',
        'State': 'NC',
        'TZ': -5.0,
        'latitude': 36.1,
        'longitude': -79.95,
        'altitude': 273.0}
    assert meta == greensboro
    # February for Greensboro is 1996, a leap year, so check to make sure there
    # aren't any rows in the output that contain Feb 29th
    assert data.index[1414] == pd.Timestamp('1996-02-28 23:00:00-0500')
    assert data.index[1415] == pd.Timestamp('1996-03-01 00:00:00-0500')
    # now check if it parses correctly when we try to coerce the year
    data, _ = read_tmy3(TMY3_FEB_LEAPYEAR, coerce_year=1990,
                        map_variables=False)
    # if get's here w/o an error, then gh865 is fixed, but let's check anyway
    assert all(data.index[:-1].year == 1990)
    assert data.index[-1].year == 1991
    # let's do a quick sanity check, are the indices monotonically increasing?
    assert all(np.diff(data.index.view(np.int64)) == 3600000000000)
    # according to the TMY3 manual, each record corresponds to the previous
    # hour so check that the 1st hour is 1AM and the last hour is midnite
    assert data.index[0].hour == 1
    assert data.index[-1].hour == 0


@pytest.fixture
def solaranywhere_index():
    return pd.date_range('2021-01-01 01:00:00-05:00', periods=8760, freq='1h')


def test_solaranywhere_tmy3(solaranywhere_index):
    # The SolarAnywhere TMY3 format specifies midnight as 00:00 whereas the
    # NREL TMY3 format utilizes 24:00. The SolarAnywhere file is therefore
    # included to test files with  00:00 timestamps are parsed correctly
    data, meta = tmy.read_tmy3(TMY3_SOLARANYWHERE, encoding='iso-8859-1',
                               map_variables=False)
    pd.testing.assert_index_equal(data.index, solaranywhere_index)
    assert meta['USAF'] == 0
    assert meta['Name'] == 'Burlington  United States'
    assert meta['State'] == 'NA'
    assert meta['TZ'] == -5.0
    assert meta['latitude'] == 44.465
    assert meta['longitude'] == -73.205
    assert meta['altitude'] == 41.0
