#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""


"""
from __future__ import print_function

import os
import sys
import utsusemi.SAS.ana.Reduction.EditWiringFile as ED

#[inamura 170223]-->
import Manyo
import Manyo.MLF as mm
import Manyo.Utsusemi as mu

class EditRPMTWiringInfo(object):
    def __init__(self,filename=""):
        """
        """
        self.BP = None
        if filename!="":
            self.Load(filename)


    def Load(self,filename):
        self.BP=mm.BoostXmlParser()
        if self.BP.Load(filename):
            pass
        else:
            del self.BP
            self.BP=None
            raise UserWarning("EditRPMTWiringInfo::Load > Failed to read file (%s)"%filename)

    def set_FrameInfo(self,frameNo=0, boundary=0.0):
        if self.BP==None:
            return false

        #<frameInfo frameNo="0" boundary="0.000000" />"
        if self.BP.hasPath("/wiringInfo/frameInfo"):
            v_att = Manyo.MakeStringVector(2)
            v_val = Manyo.MakeStringVector(2)
            v_att[0]="frameNo"
            v_val[0]="%d"%(frameNo)
            v_att[1]="boundary"
            v_val[1]="%g"%(boundary)
            self.BP.AddElement("/wiringInfo/frameInfo",v_att,v_val)

    def SaveToXml(self, outfile ):
        if self.BP==None:
            return false

        return self.BP.Save(outfile)

    def change_TofBinPattern(self, type,cont_in):
        if self.BP==None:
            raise UserWarning("Did not set xml file.")
        if len(cont_in)!=3:
            raise UserWarning("TofBInPattern is invalid.")
        params = "%g,%g,%g"%(cont_in[0],cont_in[1],cont_in[2])
        if self.BP.hasPath("/wiringInfo/tofBinPatternList/tofBinPattern,i=0"):
            v_att = Manyo.MakeStringVector(3)
            v_val = Manyo.MakeStringVector(3)
            v_att[0]="i"
            v_val[0]="0"
            v_att[1]="patternId"
            v_val[1]="0"
            v_att[2]="type"
            v_val[2]="%d"%(int(type))
            self.BP.AddElement("/wiringInfo/tofBinPatternList/tofBinPattern,i=0",v_att,v_val)
            self.BP.AddElement("/wiringInfo/tofBinPatternList/tofBinPattern,i=0",params)
        return 0 #patternId

    def setall_TofBinInfo(self,ptnId,offsetbin,maskId=0):
        v_att = Manyo.MakeStringVector(3)
        v_val = Manyo.MakeStringVector(3)
        v_att[0]="i"
        v_val[0]="0"
        v_att[1]="patternId"
        v_val[1]="%d"%(ptnId)
        v_att[2]="offsetBin"
        v_val[2]="%d"%(offsetbin)
        if maskId!=0:
            v_att.append("maskPtnId")
            v_val.append("%d"%(maskId))

        self.BP.AddElement("/wiringInfo/tofBinInfo/tofBin",v_att,v_val)
        self.BP.AddElement("/wiringInfo/tofBinInfo/tofBin,i=0","All")


    def set_TofMask(self,maskId=0,tofMask=""):
        v_att = Manyo.MakeStringVector(1)
        v_val = Manyo.MakeStringVector(1)
        v_att[0]="n"
        v_val[0]="1"
        self.BP.AddElement("/wiringInfo/tofMaskPatternList",v_att,v_val)
        del v_att,v_val
        v_att = Manyo.MakeStringVector(2)
        v_val = Manyo.MakeStringVector(2)
        v_att[0]="i"
        v_val[0]="0"
        v_att[1]="maskPtnId"
        v_att[1]="%d"%(maskId)
        self.BP.AddElement("/wiringInfo/tofMaskPatternList/tofMaskPattern",v_att,v_val)
        self.BP.AddElement("/wiringInfo/tofMaskPatternList/tofMaskPattern",tofMask)



class SASMakeParamFiles(object):
    def __init__(self, runNo, detType="PSD" ):
        """
        Constructor

        @param isAfter2013B (bool)
        @return None
        """
        self.CommentHead = "SASMakeParamFiles::"
        self.isStatus = False

        self.XaxisDic={"tof":2,"dl":23,"dl/l":24}

        self.OrgWiringInfo = ""
        self.DetectorInfo = ""
        det_mod = 0
        if detType=="PSD":
            det_mod = 0
        elif detType=="MON1":
            det_mod = 1
        elif detType=="MON2":
            det_mod = 2
        elif detType=="RPMT":
            det_mod = 3
        else:
            raise UserWarning("detType is invalid.")

        UAE = mu.UtsusemiAnaEnvironReader("environ_ana.xml")
        if not UAE.Status:
            raise UserWarning("environ_ana.xml not found.")

        tmp_files = UAE.PutParamFiles(runNo,det_mod)
        if tmp_files.size()<2:
            raise UserWarning("WiringInfo, DetectorInfo are not found.")
        else:
            self.OrgWiringInfo = tmp_files[0]
            self.DetectorInfo = tmp_files[1]


        ##[inamura 170223]-->
        self.isRPMT = False
        if detType=="RPMT":
            self.OrgWiringInfo = "WiringInfoReadout_RPMT.xml"
            self.DetectorInfo = "DetectorInfo2d_RPMT.xml"
            #self.WiringInfo = os.path.join( os.environ["UTSUSEMI_USR_DIR"],"ana","xml",self.OrgWiringInfo )
            self.WiringInfo = mu.FindParamFilePath( self.OrgWiringInfo )
            self.EDW = EditRPMTWiringInfo(self.WiringInfo)
            #self.DetectorInfo = os.path.join( os.environ["UTSUSEMI_USR_DIR"],"ana","xml",self.DetectorInfo )
            self.DetectorInfo = mu.FindParamFilePath( self.DetectorInfo )
            self.SetDetType( detType )
            self.isStatus=True
            return
        ##<--[inamura 170223]
        if runNo>0 and runNo<=200:
            self.OrgWiringInfo = "WiringInfo_after2015B.xml"
            if detType=="PSD":
                self.DetectorInfo = "DetectorInfo_after2015B.xml"
            elif detType=="MON1":
                self.DetectorInfo = "DetectorInfo_N2MON1_after2014A.xml"
            elif detType=="MON2":
                self.DetectorInfo = "DetectorInfo_N2MON2_after2014A.xml"
            self.BankInfo["SU"]=[[0]]
            self.BankInfo["SD"]=[[1]]
            self.BankInfo["SM16"]=[[6]]
            self.BankInfo["SM14"]=[[5]]
            self.BankInfo["SM"]=[[5],[6]]
            self.BankInfo["SC"]=[[7]]
            self.BankInfo["MD"]=[[11]]
            self.BankInfo["MR"]=[[4]]
            self.BankInfo["MU"]=[[8]]
            self.BankInfo["ML"]=[[12]]
            self.BankInfo["HD"]=[[2,24,27]]
            self.BankInfo["HU"]=[[2,44,47]]
            self.BankInfo["HL"]=[[2,63,67]]
            self.BankInfo["BW"]=[[9,17,21]]
            self.isStatus = True

        elif runNo>0 and runNo<=104406:
            self.OrgWiringInfo = "WiringInfo_before2013B.xml"
            if detType=="PSD":
                self.DetectorInfo = "DetectorInfo.xml"
            elif detType=="MON1":
                self.DetectorInfo = "DetectorInfo_N2MON1_before2013B.xml"
            elif detType=="MON2":
                self.DetectorInfo = "DetectorInfo_N2MON2_before2013B.xml"
            self.BankInfo["SU"]=[[0,76,91]]
            self.BankInfo["SD"]=[[1,9,24]]
            self.BankInfo["SM16"]=[[1,36,49]]
            self.BankInfo["SM14"]=[[0,50,67]]
            self.BankInfo["SM"]=[[0,50,67],[1,36,49]]
            self.BankInfo["SC"]=[[2,103,118]]
            self.BankInfo["MD"]=[[4,23,32]]
            self.BankInfo["MR"]=[[4,97,105]]
            self.BankInfo["MU"]=[[4,50,54]]
            self.BankInfo["ML"]=[[4,72,81]]
            self.BankInfo["HD"]=[[2,25,27]]
            self.BankInfo["HU"]=[[2,44,47]]
            self.BankInfo["HL"]=[[2,64,67]]
            self.BankInfo["BW"]=[[2,17,21]]
            self.isStatus = True

        elif runNo>=104407 and runNo<=105141:
            self.OrgWiringInfo = "WiringInfo_after2013B.xml"
            if detType=="PSD":
                self.DetectorInfo = "DetectorInfo_after2013B.xml"
            elif detType=="MON1":
                self.DetectorInfo = "DetectorInfo_N2MON1_after2013B.xml"
            elif detType=="MON2":
                self.DetectorInfo = "DetectorInfo_N2MON2_after2013B.xml"
            self.BankInfo["SU"]=[[0]]
            self.BankInfo["SD"]=[[1]]
            self.BankInfo["SM16"] = [[6]]
            self.BankInfo["SM14"] = [[5]]
            self.BankInfo["SM"]=[[5],[6]]
            self.BankInfo["SC"]=[[7]]
            self.BankInfo["MD"]=[[4,23,32]]
            self.BankInfo["MR"]=[[4,97,105]]
            self.BankInfo["MU"]=[[4,48,56]]
            self.BankInfo["ML"]=[[4,72,81]]
            self.BankInfo["HD"]=[[2,25,27]]
            self.BankInfo["HU"]=[[2,44,47]]
            self.BankInfo["HL"]=[[2,64,67]]
            self.BankInfo["BW"]=[[2,17,21]]
            self.isStatus = True

        elif runNo>=105142 and runNo<108542:
            self.OrgWiringInfo = "WiringInfo_after2014A.xml"
            if detType=="PSD":
                self.DetectorInfo = "DetectorInfo_after2014A.xml"
            elif detType=="MON1":
                self.DetectorInfo = "DetectorInfo_N2MON1_after2014A.xml"
            elif detType=="MON2":
                self.DetectorInfo = "DetectorInfo_N2MON2_after2014A.xml"
            self.BankInfo["SU"]=[[0]]
            self.BankInfo["SD"]=[[1]]
            self.BankInfo["SM16"] = [[6]]
            self.BankInfo["SM14"] = [[5]]
            self.BankInfo["SM"]=[[5],[6]]
            self.BankInfo["SC"]=[[7]]
            self.BankInfo["MD"]=[[4,23,32]]
            self.BankInfo["MR"]=[[4,97,105]]
            self.BankInfo["MU"]=[[4,48,56]]
            self.BankInfo["ML"]=[[4,72,81]]
            self.BankInfo["HD"]=[[2,25,27]]
            self.BankInfo["HU"]=[[2,44,47]]
            self.BankInfo["HL"]=[[2,64,67]]
            self.BankInfo["BW"]=[[2,17,21]]
            self.isStatus = True

        elif runNo>=108542 and runNo<=111418:
            self.OrgWiringInfo = "WiringInfo_after2015B.xml"
            if detType=="PSD":
                self.DetectorInfo = "DetectorInfo_after2014B.xml"
            elif detType=="MON1":
                self.DetectorInfo = "DetectorInfo_N2MON1_after2014A.xml"
            elif detType=="MON2":
                self.DetectorInfo = "DetectorInfo_N2MON2_after2014A.xml"
            self.BankInfo["SU"]=[[0]]
            self.BankInfo["SD"]=[[1]]
            self.BankInfo["SM16"] = [[6]]
            self.BankInfo["SM14"] = [[5]]
            self.BankInfo["SM"]=[[5],[6]]
            self.BankInfo["SC"]=[[7]]
            self.BankInfo["MD"]=[[4,23,32]]
            self.BankInfo["MR"]=[[4,97,105]]
            self.BankInfo["MU"]=[[8,48,56]]
            self.BankInfo["ML"]=[[8,72,81]]
            self.BankInfo["HD"]=[[2,25,27]]
            self.BankInfo["HU"]=[[2,44,47]]
            self.BankInfo["HL"]=[[2,64,67]]
            self.BankInfo["BW"]=[[9,17,21]]
            self.isStatus = True

        elif runNo>=111419 and runNo<=114436:
            self.OrgWiringInfo = "WiringInfo_after2016A.xml"
            if detType=="PSD":
                self.DetectorInfo = "DetectorInfo_after2016A.xml"
            elif detType=="MON1":
                self.DetectorInfo = "DetectorInfo_N2MON1_after2014A.xml"
            elif detType=="MON2":
                self.DetectorInfo = "DetectorInfo_N2MON2_after2016A.xml"
            self.BankInfo["SU"]=[[0]]
            self.BankInfo["SD"]=[[1]]
            self.BankInfo["SM16"] = [[6]]
            self.BankInfo["SM14"] = [[5]]
            self.BankInfo["SM"]=[[5],[6]]
            self.BankInfo["SC"]=[[7]]
            self.BankInfo["MD"]=[[11]]
            self.BankInfo["MR"]=[[4]]
            self.BankInfo["MU"]=[[8]]
            self.BankInfo["ML"]=[[12]]
            self.BankInfo["HD"]=[[2,24,27]]
            self.BankInfo["HU"]=[[2,44,47]]
            self.BankInfo["HL"]=[[2,63,67]]
            self.BankInfo["BW"]=[[9,17,22]]
            self.isStatus = True
        elif runNo>=114437 and runNo<=400000:
            self.OrgWiringInfo = "WiringInfo_after2016A_N2MonTest_170304.xml"
            if detType=="PSD":
                self.DetectorInfo = "DetectorInfo_after2016A.xml"
            elif detType=="MON1":
                self.DetectorInfo = "DetectorInfo_N2MON1_after2014A.xml"
            elif detType=="MON2":
                self.DetectorInfo = "DetectorInfo_N2MON2_after2014A.xml"
            elif detType=="MON3":
                self.DetectorInfo = "DetectorInfo_N2MON3_after2014A.xml"
            self.BankInfo["SU"]=[[0]]
            self.BankInfo["SD"]=[[1]]
            self.BankInfo["SM16"] = [[6]]
            self.BankInfo["SM14"] = [[5]]
            self.BankInfo["SM"]=[[5],[6]]
            self.BankInfo["SC"]=[[7]]
            self.BankInfo["MD"]=[[11]]
            self.BankInfo["MR"]=[[4]]
            self.BankInfo["MU"]=[[8]]
            self.BankInfo["ML"]=[[12]]
            self.BankInfo["HD"]=[[2,24,27]]
            self.BankInfo["HU"]=[[2,44,47]]
            self.BankInfo["HL"]=[[2,63,67]]
            self.BankInfo["BW"]=[[9,17,22]]
            self.isStatus = True

        else:
            return

        ##[inamura 161111]-->
        #self.WiringInfo = os.path.join( os.environ["UTSUSEMI_USR_DIR"],"ana","xml",self.OrgWiringInfo )
        self.WiringInfo = mu.FindParamFilePath( self.OrgWiringInfo )
        #path_w = os.path.join( os.environ["UTSUSEMI_USR_DIR"],"ana","xml",self.OrgWiringInfo )
        #path_w = os.path.join( "/home/mlfdev/dev/TestScripts/xml", self.OrgWiringInfo )
        #self.EDW = ED.EditWiringInfo( path_w )
        self.EDW = ED.EditWiringInfo( self.WiringInfo )
        ##<--[inamura 161111]

        #self.DetectorInfo = os.path.join( os.environ["UTSUSEMI_USR_DIR"],"ana","xml",self.DetectorInfo )
        self.DetectorInfo = mu.FindParamFilePath( self.DetectorInfo )

        self.SetDetType( detType )


    def SetDetType( self, _detType ):
        if _detType=="PSD":
            self.EDW.SelectByDetType( "PSD" )
        elif _detType=="MON1":
            self.EDW.SelectByDetType( "N2MON1" )
        elif _detType=="MON2":
            self.EDW.SelectByDetType( "N2MON2" )
        elif _detType=="MON3":
            self.EDW.SelectByDetType( "N2MON3" )
        elif _detType=="RPMT": #[inamura 170223]
            pass
        else:
            self.isStatus = False
            return

    def SetBank( self, bankName=""):
        """
        Sets Bank Name and make wiringInfo.xml for only this bank

        @param bankName (string) "SU","SD","SM","SC",MD","MR",MU",ML","HD","HU","HL","BW"
        @return path/to/wiringInfo.xml
        """
        if (bankName=="") or (bankName.upper().replace(" ","")=="ALL"):
            return 0

        bank_sep_st = bankName.upper().split(" ")
        bankName_list = []  ## list of Bank Names
        for bb in bank_sep_st:
            if bb in self.BankInfo:
                bankName_list.append( bb )
            else:
                print(self.CommentHead+"SetBank >> bankName is invalid and ignored ("+bb+")")

        if len(bankName_list)==0:
            print(self.CommentHead+"SetBank >> bankName is invalid ("+bankName+")")
            return -1

        self.EDW.SuspendDaq()  # all detectors are suspended

        for bankName in bankName_list:
            bankinfo = self.BankInfo[bankName]
            for daqlist in bankinfo:
                if len(daqlist)==1:
                    print("bankName,daqlist[0]=",bankName,daqlist[0])
                    self.EDW.ResumeDaq(daqlist[0])
                elif len(daqlist)==3:
                    for mod in range( daqlist[1], (daqlist[2]+1) ):
                        print("bankName,daqlist=",bankName,daqlist)
                        self.EDW.ResumeModules( daqlist[0], mod )
                else:
                    print(self.CommentHead+"SetBank >> bankInfo is invalid daqlist =",daqlist)
                    return -1

        return 0


    def Save( self ):
        import platform
        outfile = ""
        if platform.system()=="Windows":
            outfile = "SAS_%06d_%s" % (os.getpid(),self.OrgWiringInfo)
        else:
            outfile = "%s_SAS_%06d_%s" % (os.environ["USER"],os.getpid(),self.OrgWiringInfo)
        #outfile = os.path.join( os.environ["UTSUSEMI_USR_PRIV_HOME"],"ana","tmp",outfile )
        outfile = os.path.join( mu.UtsusemiEnvGetUserDir(),"ana","tmp",outfile )
        self.EDW.SaveToXml( outfile )

        return outfile

    def SetXaxis( self, Params="0 40000 100 tof"):
        self.SetXaxisAll( Params )


    def SetXaxisAll( self, Params="0 40000 100 tof", TofMask="" ):
        p_list=Params.split(" ")
        if len(p_list)!=4:
            raise UserWarning("param error")

        params_list = []
        for i in range(3):
            print("P_list=",p_list[i])
            params_list.append( float(p_list[i]) )
        AxType=p_list[3].lower()
        if not AxType in ["dl","dl/l","tof"]:
            raise UserWarning("param error about AxType")

        ptnId = self.EDW.change_TofBinPattern(type=self.XaxisDic[ AxType ],cont_in=params_list)
        if TofMask=="":
            self.EDW.setall_TofBinInfo(ptnId,0)
        else:
            tof_mask_id = 0
            self.EDW.set_TofMask(tof_mask_id, TofMask)
            self.EDW.setall_TofBinInfo(ptnId,0,tof_mask_id)
        print(self.CommentHead+"AxType=",AxType,", Params = ",Params," TofMask=",TofMask)

    """
    def SetDetType( self, DetType="PSD" ):
        if DetType=="PSD":
            self.EDW.SelectByDetType( "PSD" )
            if (self.isAfter2013B):
                self.DetectorInfo = "DetectorInfo_after2013B.xml"
            else:
                self.DetectorInfo = "DetectorInfo.xml"
        elif DetType=="MON1":
            self.EDW.SelectByDetType( "N2MON1" )
            if (self.isAfter2013B):
                self.DetectorInfo = "DetectorInfo_N2MON1_after2013B.xml"
            else:
                self.DetectorInfo = "DetectorInfo_N2MON1_before2013B.xml"
        elif DetType=="MON2":
            self.EDW.SelectByDetType( "N2MON2" )
            if (self.isAfter2013B):
                self.DetectorInfo = "DetectorInfo_N2MON2_after2013B.xml"
            else:
                self.DetectorInfo = "DetectorInfo_N2MON2_before2013B.xml"

        else:
            print self.CommentHead+"SetDetType : Invalid DetType"

    """

if __name__ == '__main__':
    if len(sys.argv)==3:
        if ( sys.argv[1] in ["True","False"] ):
            if ( sys.argv[1]=="True" ):
                tt=SASMakeParamFiles( True )
            else:
                tt=SASMakeParamFiles( False )
            tt.SetBank( sys.argv[2] )
            tt.SetXaxis("dL","0.7 7.7 0.05" )
            fp = tt.Save()
            print("WiringInfo=", fp)
