#!/bin/env python
# -*- coding: utf-8 -*-
#
# Usage: runlist.py initial_run_no [final_run_no]
#    initial_run_no, final_run_no:
#       range of run numbers to be listed.
#    -np: does not show proton counts

from __future__ import print_function
import sys
import os
import glob
import Manyo as mm
import Manyo.Utsusemi as mu
import utsusemi.ana.Reduction.BaseCommands as BC

ver = float(sys.version_info[0]) + float(sys.version_info[1]) * 0.1
if ver < 2.5:
    from elementtree.ElementTree import ElementTree
else:
    from xml.etree.ElementTree import ElementTree

#########################################


def usage(argv):
    print("------------------------------------------------------------------------")
    print("Usage  %s [option] initial_run_no [final_run_no]" % (argv[0]))
    print("       initial_run_no, final_run_no : range of run numbers to be listed.")
    print("------------------------------------------------------------------------")
    print("Option")
    print("       -np         : does not show proton counts")
    print("       -f filename : saves the list as a text file named filename")
    print("------------------------------------------------------------------------")
    sys.exit(0)

#########################################
# copied from GetMeasBC.py by Y. Inamura


def GetMeasBC(runNo, flag_proton, offset_sec=0.0, isCT8Neutron=False):
    TT = mu.T0TreatToolsNeunet()
    st_RUNNO = "%3s%06d" % (os.environ["UTSUSEMI_INST_CODE"], runNo)

    root_data_dir = os.environ["UTSUSEMI_DATA_DIR"]
    inst_code = os.environ["UTSUSEMI_INST_CODE"]
    list_DATA_folder = os.listdir(root_data_dir)
    target_dir = ""

    list_DATA_folder.sort()
    for a_DATA_folder in list_DATA_folder:
        if a_DATA_folder.find(inst_code) < 0:
            continue

        a_path = os.path.join(root_data_dir, a_DATA_folder)
        if os.path.isdir(a_path):
            list_DATA = os.listdir(a_path)
            for a_data_dir in list_DATA:
                if a_data_dir.find(st_RUNNO) == 0:
                    target_dir = os.path.join(a_path, a_data_dir)
                    break
        if target_dir != "":
            break

    if target_dir == "":
        err_message = "There is no data;{}".format(st_RUNNO)
        raise UserWarning(err_message)
    print("target_dir={}".format(target_dir))
    edb_list = glob.glob(target_dir + "/*.edb")
    edb_list.sort()
    first_file = edb_list[0]
    edb_list = glob.glob(target_dir + "/%s*.edb" % (first_file[-24:-7]))
    edb_list.sort()

    if len(edb_list) == 0:
        err_message = "There is no edb data;{}".format(st_RUNNO)
        raise UserWarning(err_message)
    target_edb = mm.MakeStringVector()
    for a_file in edb_list:
        target_edb.append(a_file)

    TT.readOrgEvent(target_edb)
    mpv2 = TT.putMeasPeriodFromT0()

    mpv = mm.MakeDoubleVector()
    for i in range(7):
        mpv.append(mpv2[i])
    for i in range(7):
        mpv.append(mpv2[mpv2.size() - 1 - 6 + i])
    if mpv.size() != 14:
        err_message = "False to get measuring period from Event Data"
        raise UserWarning(err_message)
    start_date = "%04d/%02d/%02d" % (int(mpv[0]), int(mpv[1]), int(mpv[2]))
    start_time = "%02d:%02d:%02d" % (int(mpv[3]), int(mpv[4]), int(mpv[5]))
    end_date = "%04d/%02d/%02d" % (int(mpv[7]), int(mpv[8]), int(mpv[9]))
    end_time = "%02d:%02d:%02d" % (int(mpv[10]), int(mpv[11]), int(mpv[12]))

    proton = "     ---  "
    kicker = "     ---  "
    if flag_proton == 0:  # does not show proton counts
        pass
    else:  # show proton counts
        #        print "NormByBeamCurrent(runNo=%d)" % runNo
        #        print "     begin date and time = ",start_date," ",start_time
        #        print "       end date and time = ",end_date," ",end_time
        if flag_proton == 1 or flag_proton == 3:
            bc, ratio, org_bc = BC.getBeamCurrentWithCorrectRatio(
                start_date, start_time, end_date, end_time, offset_sec, isCT8Neutron)
            proton = "%14.4f" % (bc)
        if flag_proton == 2 or flag_proton == 3 or flag_proton == 4:
            kk = TT.PutT0Index()
            kicker = "%10d" % (int(kk.size()))
        if flag_proton == 4:
            bc, ratio, org_bc = BC.getBeamCurrentWithCorrectRatio(
                start_date, start_time, end_date, end_time, offset_sec, isCT8Neutron)
            proton = "%14.4f %10g %g" % (bc, org_bc, ratio)

    del TT
    return (runNo, start_date, start_time, end_date, end_time, proton, kicker)

#########################################


def MakeRunList(argv):
    ET = ElementTree()

    Output = []  # list where the output is stored

    # header of the output
    # Output.append("  run#           start                 end              protons     T_A    T_B     gonio")

    argc = len(argv)  # number of argument
    if (argc < 2):
        usage(argv)  # show help and exit

    flag_proton = 1
    offset_sec = 0.0
    # analysis arguments
    output_name = ""
    init_no = -1
    fin_no = -1
    ind = 1
    isCT8Neutron = False
    while(True):
        if argv[ind] == "-np":  # if no use of procton current
            flag_proton = 0
        elif argv[ind] == "-p":
            flag_proton = 1
        elif argv[ind] == "-k":
            flag_proton = 2
        elif argv[ind] == "-pk" or argv[ind] == "-kp":
            flag_proton = 3
        elif argv[ind] == "-a" or argv[ind] == "-all":
            flag_proton = 4
        elif argv[ind] == "-f":  # set output file
            if ind == (len(argv) - 1):
                usage(argv)
            ind += 1
            output_name = argv[ind]
        elif argv[ind] == "-os":  # if use offset seconds for measurement periods
            if ind == (len(argv) - 1):
                usage(argv)
            ind += 1
            offset_sec = float(argv[ind])
        elif argv[ind] == "-CT8n":  # if use CT8Neutron
            isCT8Neutron = True
            # ind +=1
        else:
            if init_no < 0:
                init_no = int(argv[ind])
            else:
                fin_no = int(argv[ind])

        ind += 1
        if ind >= len(argv):
            break

    if init_no < 0:
        usage(argv)
    if fin_no < 0:
        fin_no = init_no

    run_no = init_no  # run number

    if isCT8Neutron:
        proton_source = "CT8n"
    else:
        proton_source = "CT9"
    if flag_proton == 0 or flag_proton == 1:
        Output.append(
            "  run#           start                 end              protons(%s)     T_A    T_B     gonio" % (proton_source))
    elif flag_proton == 2:
        Output.append(
            "  run#           start                 end                kickers     T_A    T_B     gonio")
    elif flag_proton == 3:
        Output.append(
            "  run#           start                 end                kickers    protons(%s)     T_A    T_B     gonio" % (proton_source))
    elif flag_proton == 4:
        Output.append(
            "  run#           start                 end           kickers        protons       %s   ratio     T_A    T_B     gonio" % proton_source)

    while(True):
        # xml file where the experimental condition is stored
        file = "%3s%06d.xml" % (os.environ["UTSUSEMI_INST_CODE"], run_no)
        file = os.path.join(os.environ["UTSUSEMI_USR_DIR"], "exp", "xml", file)

        # open the xml file
        e = ET.parse(open(file))

        # read the run number from xml file to check consistency
        runno = e.find(".//runNo").text
        runno = int(runno)

        # read set temperature
        temp_el = e.find(".//temperature")
        if temp_el is None:
            temp = "  --- "
        else:
            temp = "%6.2f" % (float(temp_el.text))

        # read temperature A
        temp_a_el = e.find(".//temperature_a")
        if temp_a_el is None:
            temp_a = "set_T="
        else:
            temp_a = "%6.2f" % (float(temp_a_el.text))

        # read temperature B
        temp_b_el = e.find(".//temperature_b")
        if temp_b_el is None:
            temp_b = temp
        else:
            temp_b = "%6.2f" % (float(temp_b_el.text))

        # read angle of the gonio
        gonio_el = e.find(".//curPos")
        if gonio_el is None:
            gonio = "    ---    "
        else:
            gonio = "%8.4f" % (float(gonio_el.text))

        # get proton current
        (runNo, s_date, s_time, e_date, e_time, proton, kicker) = GetMeasBC(
            runno, flag_proton, offset_sec, isCT8Neutron)

        # store the output in the list
        cnt = ""
        if flag_proton == 0 or flag_proton == 1:
            cnt = "%6d   %s %s   %s %s     %s   %s %s   %s" % (
                runno, s_date, s_time, e_date, e_time, proton, temp_a, temp_b, gonio)
        elif flag_proton == 2:
            cnt = "%6d   %s %s   %s %s     %s   %s %s   %s" % (
                runno, s_date, s_time, e_date, e_time, kicker, temp_a, temp_b, gonio)
        elif flag_proton == 3:
            cnt = "%6d   %s %s  %s %s      %s   %s   %s %s %s" % (
                runno, s_date, s_time, e_date, e_time, kicker, proton, temp_a, temp_b, gonio)
        elif flag_proton == 4:
            cnt = "%6d   %s %s  %s %s %s %s   %s %s %s" % (
                runno, s_date, s_time, e_date, e_time, kicker, proton, temp_a, temp_b, gonio)

        Output.append(cnt)

        run_no += 1
        if run_no > fin_no:
            break

    print()  # print blank line
    print("-----------------------------------------------------------------------------------------------------------------------")
    for out in Output:  # print the output
        print(out)
    print("-----------------------------------------------------------------------------------------------------------------------")

    # save as text file
    if output_name != "":
        print("     Output file={}".format(output_name))
        fo = open(output_name, "w")
        for out in Output:
            fo.write(out + "\n")
        fo.close()

#########################################


if __name__ == '__main__':
    MakeRunList(sys.argv)
