#!/usr/bin/python
# -*- coding: utf-8 -*-

import multiprocessing
from optparse import OptionParser
import os
import re
import platform
import sys

from PySide2 import QtCore, QtGui, QtWidgets
#from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication,QFileDialog,QListWidgetItem,QMessageBox
from PySide2.QtCore import QFile

from ui_PySide_DlgSetUtsusemiEnv import Ui_MainWindow

if sys.platform == 'win32':
    HOME = os.environ.get("USERPROFILE")
elif sys.platform == 'darwin':
    HOME = os.environ.get("HOME")
elif sys.platform == 'linux2':
    HOME = os.environ.get("HOME")
else:
    HOME = os.curdir

# UTSUSEMI_DATA_DIRとUTSUSEMI_USR_DIRのベースディレクトリの初期値
DATA_DIR = os.path.join(HOME, "Documents", "MLF")

# "utsusemienv.cfg"のパス
FILE_CONFIG = os.environ.get("CONFFILE_ENV")
FILE_CONFIG_DIR = os.path.dirname(FILE_CONFIG)

# カレントディレクトリ
CURRENT_DIR = os.getcwd()

# 設定対象の環境変数
UTSUSEMI_INST_CODE = "UTSUSEMI_INST_CODE"
UTSUSEMI_LOG_QUIET = "UTSUSEMI_LOG_QUIET"
UTSUSEMI_DEBUG_MODE = "UTSUSEMI_DEBUG_MODE"
UTSUSEMI_MULTH = "UTSUSEMI_MULTH"
UTSUSEMI_DATA_DIR = "UTSUSEMI_DATA_DIR"
UTSUSEMI_USR_DIR = "UTSUSEMI_USR_DIR"

# ビームライン選択用の辞書
BEAMLINES = {
    "SIK": {'line':  1, 'name': "4SEASONS"},
    "HPN": {'line': 11, 'name': "PLANET"},
    "AMR": {'line': 14, 'name': "AMATERAS"},
    "SAS": {'line': 15, 'name': "TAIKAN"},
}

# Y/N←→真偽値 変換用の辞書
LOG_QUIET = {"Y": True, "N": False}

class Param:
    def __init__(self):
        self.data_dir = os.path.join(DATA_DIR, "DATA")
        self.usr_dir = os.path.join(DATA_DIR, "HOME")
        self.multh = 2 if multiprocessing.cpu_count() >= 2 else 1
        self.log_quiet = True
        self.debug_mode = False
        self.inst_code = "SIK"
        self.loaded = {"UTSUSEMI_" + x:False for x in "MULTH,INST_CODE,LOG_QUIET,DEBUG_MODE,USR_DIR,DATA_DIR".split(",")}

    def load(self, path):
        if not os.path.isfile(path):
            return
        try:
            with open(path) as f:
                d = {}
                for x in f.readlines():
                    if "=" in x:
                        key,val = x.strip().split("=",1)
                        d[key] = re.sub(r'[\"\'\n\r]+', '', val)
                for key,val in d.items():
                    msg = ""
                    if key == "UTSUSEMI_MULTH":
                        try:
                            self.multh = int(val)
                        except:
                            msg = "MULTH: not an integer: >>>" + val + "<<<"
                    elif key == "UTSUSEMI_INST_CODE":
                        self.inst_code = val
                    elif key == "UTSUSEMI_LOG_QUIET":
                        if val in ("Y","N"):
                            self.log_quiet = ("Y" == val)
                        else:
                            msg = "LOG_QUIET: illegal value: >>>" + val + "<<<"
                    elif key == "UTSUSEMI_DEBUG_MODE":
                        if val in ("Y","N"):
                            self.debug_mode = ("Y" == val)
                        else:
                            msg = "DEBUG_MODE: illegal value: >>>" + val + "<<<"
                    elif key == "UTSUSEMI_USR_DIR":
                        self.usr_dir = val
                    elif key == "UTSUSEMI_DATA_DIR":
                        self.data_dir = val.strip('"')
                    if key in self.loaded.keys() and not msg:
                        self.loaded[key] = True
                    if msg:
                        QMessageBox.warning(None,"PARAMETER ERROR",msg)
        except Exception as e:
            QMessageBox.warning(None,"LOAD ERROR","unknown load error: " + str(e))


    def bad_paths(self):
        d = self.data_dir
        u = self.usr_dir
        ret = []
        if not os.path.exists(d) or not os.path.isdir(d):
            ret.append(d)
        if not os.path.exists(u) or not os.path.isdir(u):
            ret.append(u)
        return ret


    def dump(self, path):
        bad = self.bad_paths()
        if bad:
            return bad
        with open(path,"w") as f:
            f.write("UTSUSEMI_INST_CODE="+self.inst_code+"\n")
            f.write("UTSUSEMI_LOG_QUIET="+("Y" if self.log_quiet else "N") +"\n")
            f.write("UTSUSEMI_DEBUG_MODE="+("Y" if self.debug_mode else "N") +"\n")
            f.write("UTSUSEMI_MULTH="+str(self.multh)+"\n")
            f.write("UTSUSEMI_DATA_DIR=\""+self.data_dir+"\"\n")
            f.write("UTSUSEMI_USR_DIR=\""+self.usr_dir+"\"\n")
        return []

class Main(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent):
        #file = QFile(path)
        #file.open(QFile.ReadOnly)
        #loader = QUiLoader()
        #self = loader.load(file)
        super(Main, self).__init__(parent)
        self.param = Param()
        self.setupUi(self)
        self.setup()
        self.connections()
        self.show()


    def setup(self):
        self.items = {}
        for x,vs in BEAMLINES.items():
            s = "BL" + str(vs['line']).zfill(2) + ":" + x + "(" + vs['name'] + ")"
            item = QListWidgetItem(s)
            self.beamList.addItem(item)
            self.items[x] = item
        self.beamList.setCurrentItem(self.items["SIK"])

        self.spinThreads.setRange(1,multiprocessing.cpu_count())
        if FILE_CONFIG is None:
            msg = """You need to define an environment variable 'CONFFILE_ENV'
whose value is the filepath of utsusemienv.cfg"""
            QMessageBox.critical(self,"Missing CONFFILE_ENV",msg)
            sys.exit(1)
        self.param.load(FILE_CONFIG)
        self.textData.setPlainText(self.param.data_dir)
        self.textPriv.setPlainText(self.param.usr_dir)
        self.spinThreads.setValue(self.param.multh)
        if self.param.log_quiet:
            print("QUIET")
            self.checkYes.setChecked(True)
        if self.param.debug_mode:
            print("DEBUG_MODE")
            self.checkDebug.setChecked(True)            
        self.beamList.setItemSelected(self.items[self.param.inst_code],True)

    def connections(self):
        self.buttonBox.accepted.connect(self.save)
        self.buttonBox.rejected.connect(self.quit)
        self.browseData.clicked.connect(self.fdData)
        self.browsePriv.clicked.connect(self.fdPriv)

    def quit(self, force=True):
        if force:
            app.exit()

    def fdData(self):
        UTSUSEMI_DATA_DIR = QFileDialog.getExistingDirectory(self,"DD",self.param.data_dir)
        self.textData.setPlainText(UTSUSEMI_DATA_DIR)

    def fdPriv(self):
        UTSUSEMI_USR_DIR = QFileDialog.getExistingDirectory(self,"DD",self.param.usr_dir)
        self.textPriv.setPlainText(UTSUSEMI_USR_DIR)

    def save(self):
        d1 = self.textData.toPlainText()
        d2 = self.textPriv.toPlainText()
        for d in [d1,d2]:
            if not os.path.exists(d):
                msg = "Not found given folder ({}) . Do you want to make it ?".format(d)
                ret = QMessageBox().warning(None,u"Warning", msg, QMessageBox.Ok,QMessageBox.Cancel )
                if ret == QMessageBox.Ok:
                    try:
                        os.makedirs( d )
                    except:
                        QMessageBox.warning(None,"ERROR", "No permitted.")
                        return
                else:
                    self.quit()
        self.param.data_dir = d1
        self.param.usr_dir = d2
        if not os.path.exists(os.path.join(d2,"ana","xml")):
            try:
                os.makedirs(os.path.join(d2,"ana","xml"))
            except:
                QMessageBox.warning(None,"WARNING", "Failed to make ana/xml ",QMessageBox.Ok)
            try:
                os.makedirs(os.path.join(d2,"ana","tmp"))
            except:
                QMessageBox.warning(None,"WARNING", "Failed to make ana/tmp ",QMessageBox.Ok)
        #self.param.data_dir = self.textData.toPlainText()
        #self.param.usr_dir = self.textPriv.toPlainText()
        self.param.log_quiet = self.checkYes.isChecked()
        self.param.debug_mode = self.checkDebug.isChecked()        
        self.param.multh = self.spinThreads.value()
        citem = self.beamList.currentItem()
        for k,item in self.items.items():
            if item.text == citem.text:
                self.param.inst_code = k
        if not os.path.exists(FILE_CONFIG_DIR):
            os.makedirs(FILE_CONFIG_DIR)
        bad = self.param.dump(FILE_CONFIG)
        if not bad:
            msg = "new settings were saved"
            QMessageBox.information(self,"Confirmation",msg)
            self.quit()
        msg = "illegal path(s): " + ",".join(bad)
        QMessageBox.warning(self,"ILLEGAL PATHS",msg)

if __name__ == '__main__':
    parser = OptionParser(usage=u'%prog [OPTIONS]')
    parser.add_option(
        '-a', '--alert',
        help='Display alert.',
        action='store_true',
        default=False,
        dest='isAlert'
    )
    parser.add_option(
        '-m', '--message',
        help='Alert message to be shown',
        default=None,
        dest='message')
    (option, args) = parser.parse_args()

    app = QApplication(sys.argv)

    if option.isAlert:
        msg = "\n".join([option.message,
                         "",
                         "Run the [Utsusemi Environment Settings] and set up the environment variables."])
        QMessageBox.critical(None,"Missing CONFFILE_ENV",msg)
        sys.exit(1)

    if FILE_CONFIG is None:
        msg = "\n".join(["You need to define an environment variable 'CONFFILE_ENV'"
                         "whose value is the filepath of utsusemienv.cfg"])
        QMessageBox.critical(None,"Missing CONFFILE_ENV",msg)
        sys.exit(1)

    win = Main(None)
    sys.exit(app.exec_())








