import numpy as np
import nds2 as nds
import gpstime
import matplotlib.pyplot as plt
from pydarm.cmd._report import Report


def myround(x, base=60):

    return int(base * round(float(x)/base))


def get_data(report_ID):

    r = Report.find(report_ID)
    gps = int(r.id_gpstime().gps())

    start, end = gps-(2.5*3600), gps+(2.5*3600)
    l = []

    for channel in channel_names:
        l.append(get_channel_data(start, end, channel))

    x_minutes = np.arange(myround(start), myround(end), 60)

    return x_minutes, l, start, end, gps


def get_channel_data(start, end, channel):

    conn = nds.connection('h1nds1', 8088)
    conn.set_parameter('GAP_HANDLER', 'STATIC_HANDLER_ZERO')

    buff_min = conn.fetch(myround(start), myround(end), ["{}.min,m-trend".format(channel)])
    data_min = buff_min[0].data

    buff_mean = conn.fetch(myround(start), myround(end), ["{}.mean,m-trend".format(channel)])
    data_mean = buff_mean[0].data

    buff_max = conn.fetch(myround(start), myround(end), ["{}.max,m-trend".format(channel)])
    data_max = buff_max[0].data

    return data_min, data_mean, data_max


def get_bounds(channels):

    bounds = []

    for chan_num, c in enumerate(channels):

        pairs_min, pairs_max = [], []
        min_lower_bound, max_lower_bound = 100000, 100000

        for j in range(len(c[0])-1):

            i = j+1

            if c[0][i] != 0 and c[0][i-1] == 0:
                min_lower_bound = i-1
                pairs_min.append(min_lower_bound)
            elif c[0][i] == 0 and c[0][i-1] != 0 and i > min_lower_bound:
                min_upper_bound = i
                pairs_min.append(min_upper_bound)

            if c[2][i] != 0 and c[2][i-1] == 0:
                max_lower_bound = i-1
                pairs_max.append(max_lower_bound)
            elif c[2][i] == 0 and c[2][i-1] != 0  and i > max_lower_bound:
                max_upper_bound = i
                pairs_max.append(max_upper_bound)
                
        if len(pairs_min) % 2 != 0:
            if len(pairs_min) == 1:
                print("Error: No upper bound, so set upper bound to end of time frame.")
                pairs_min.append(len(c[0])-1)
            else:
                print("Error: channel {} has an uneven pair, {}, removing last item...".format(channel_names[chan_num], pairs_min))
                pairs_min.pop(-1)
        if len(pairs_min) == 0:
            print("Error: no pairs recovered for channel {}".format(channel_names[chan_num]))
            pairs_min += [-1, -1]
        if len(pairs_min) != 2:
            s, e = pairs_min[0], pairs_min[-1]
            pairs_min = [s, e]
                
        bounds.append(pairs_min)

    return bounds


channel_names = ["H1:SUS-ETMX_L3_CAL_EXCMON", "H1:SUS-ETMX_L2_CAL_EXCMON", "H1:SUS-ETMX_L1_CAL_EXCMON", "H1:CAL-PCALY_SWEPT_SINE_EXCMON", "H1:LSC-DARM1_EXCMON"]
report_IDs = ["20230504T055052Z", "20230505T012609Z", "20230505T174611Z", "20230506T182203Z", "20230508T180014Z", "20230509T070754Z", "20230510T062635Z", "20230517T163625Z", "20230616T161654Z", "20230620T234012Z", "20230621T191615Z", "20230621T211522Z",  "20230628T015112Z", "20230716T034950Z", "20230727T162112Z", "20230802T000812Z", "20230817T214248Z", "20230823T213958Z", "20230830T213653Z", "20230906T220850Z", "20230913T183650Z", "20230928T193609Z", "20231004T190945Z", "20231018T190729Z", "20231027T203619Z"]
bounds_sets, bounds_gps_sets = [], []

for report in report_IDs:
    try:
        print(report)
        x_minutes, channels, start, end, gps = get_data(report)
        bounds = get_bounds(channels)
        bounds_flat = list(np.concatenate(bounds))
        bounds_gps = x_minutes[bounds_flat]
        for n, i in enumerate(bounds_flat):
            if i == -1:
                bounds_gps[n] = 0
        bounds_sets.append(bounds_flat)
        bounds_gps_sets.append(bounds_gps)
    except:
        print("Report {} failed.".format(report))

rows = np.array(report_IDs)[:, np.newaxis]
with open("measurement_gps_times.csv", "w+") as f:
    np.savetxt(f, np.hstack((rows, bounds_gps_sets)), delimiter = ", ",
               header = ", SUS-ETMX_L3 lower bound, SUS-ETMX_L3 upper bound, SUS-ETMX_L2 lower bound, SUS-ETMX_L2 upper bound, SUS-ETMX_L1 lower bound, SUS-ETMX_L1 upper bound, CAL-PCALY lower bound, CAL-PCALY upper bound, LSC-DARM1 lower bound, LSC-DARM1 upper bound", fmt = "%s")