#!/usr/bin/env python
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#Process the database for essential pathways
#Essential Pathways v1.0
#Author:realasking
#Email:realasking@gmail.com,tomwangsim@163.com
#Aug-06,2017,in USTB
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
import sys
import os
import re
import sqlite3
import shutil
from epw import displayops as dpops
from epw import cmds
from epw import einit as ei
from prettytable import PrettyTable

__version__ = '1.0'
__author__ = 'realasking <realasking@gmail.com,tomwangsim@163.com>'
__license__ = 'LGPLv3'

class pathwayops(ei.einit):
      #def __init__(self,df,mn,mf): 
      def __init__(self,conf_folder,dbfile,module_name):
          ei.einit.__init__(self,conf_folder,dbfile,module_name)
          if not os.path.isfile(self.df):
             self.epwdb=sqlite3.connect(self.df)
             self.db=self.epwdb.cursor() 
             self.db.execute('''CREATE TABLE ep(pathway_name text,folder_path text,comment text)''') 
             self.epwdb.commit()
          else:
             self.epwdb=sqlite3.connect(self.df)
             self.db=self.epwdb.cursor()
          #self.module_name=mn
          #self.module_file=mf
          self.info=cmds.warnings()
          self.cmds=cmds.ops()
      
      def close(self):
             self.epwdb.close()

      def dbdelete(self,pn):
             self.db.execute('DELETE FROM ep WHERE pathway_name=?',(pn,))
             self.epwdb.commit()

      def dbcheck(self):
          #Please unload module epath in system before use this function
          self.db.execute('DELETE FROM ep WHERE rowid NOT IN (SELECT min(rowid) FROM ep GROUP BY folder_path)')
          self.epwdb.commit()
          self.db.execute('DELETE FROM ep WHERE rowid NOT IN (SELECT min(rowid) FROM ep GROUP BY pathway_name)')
          self.epwdb.commit()
          #Delete the pathways which conflict with other environment variables of the system
          for i in os.popen('env|cut -d\"=\" -f1').read().splitlines():
                self.dbdelete(i)
    
      def module_create(self):
          fp=open(self.module_file,'w')
          fp.write("#%Module1.0"+'\n')
          fp.write("               ## Module settings for essential pathways \n")
          fp.write("               ## This file is automatically generated by ep, do not modify it manually\n")
          fp.write("               proc ModulesHelp { } {\n")
          fp.write("                   puts stderr \"Essential Pathways are defined in this file,do not modify it manually\"\n")
          fp.write("               }\n")
          fp.write("\n")
          fp.write("               module-whatis \"Essential Pathways\"\n")
          self.dbcheck()
          for row in self.db.execute('SELECT * FROM ep ORDER BY pathway_name'):
              fp.write("               setenv "+row[0]+" \""+row[1]+"\"\n")    
          fp.close()

      #In consideration
      def path_mod(self):
          #remove duplicates in db 
          self.dbcheck()
          #Check if module file exists
          if os.path.isfile(self.module_file):
             os.remove(self.module_file)

      def path_refresh(self):
          #self.dbcheck()
          #Check if module file exists
          if os.path.isfile(self.module_file):
          #Check if module file has pathways undfined in db
            for i in os.popen('module show '+self.module_name+' |grep setenv|awk \'{for(i=2;i<=NF;i++) printf $i" ";print""}\'').read().splitlines():
                  #split a string at the first blank
                  sbuff=i.strip().split(' ',1)
                  j=self.db.execute('SELECT * FROM ep WHERE pathway_name=?',(sbuff[0],))
                  if len(j.fetchall())==0:
                     self.db.execute('''INSERT INTO ep VALUES(?,?,?)''',(sbuff[0],sbuff[1],''))
                     self.epwdb.commit()
                  else:
                     for k in j.fetchall():
                         if sbuff[1]!=k[1]:
                            self.db.execute('UPDATE ep SET folder_path=? WHERE pathway_name=?',(sbuff[1],sbuff[0]))
                            self.epwdb.commit()
          os.remove(self.module_file)
          self.module_create()
          self.close()

      def path_list(self):
          print('Defined PATHWAYS:')
          screeninfo=dpops.screenformat()
          screeninfo.size_calc(3)
          #fplen,namelen,waylen=screeninfo.size_calc(3)
          t1 = PrettyTable(['PATHWAY NAME', 'FOLDER PATH', 'COMMENT'])
          t1.align['PATHWAY NAME']='c'
          t1.padding_width = 1
          for row in self.db.execute('SELECT * FROM ep ORDER BY pathway_name'):
              row_1=screeninfo.string_formatting(row[0],screeninfo.namelengthmax)
              row_2=screeninfo.string_formatting(row[1],screeninfo.waylengthmax)
              row_3=screeninfo.string_formatting(row[2],screeninfo.waylengthmax)
              t1.add_row([row_1,row_2,row_3])
          print(t1)
          screeninfo2=dpops.screenformat()
          screeninfo2.size_calc(2)
          #fplen,namelen,waylen=screeninfo2.size_calc(2)
          print('Set PATHWAYS:')
          t2 = PrettyTable(['PATHWAY NAME', 'FOLDER PATH'])
          t2.align['PATHWAY NAME']='c'
          t2.padding_width = 1 
          for row1 in os.popen('module show '+self.module_name+' |grep setenv|awk \'{for(i=2;i<=NF;i++) printf $i" ";print""}\'').read().splitlines():
              tbuff=row1.strip().split(' ',1)
              row1_1=screeninfo2.string_formatting(tbuff[0],screeninfo2.namelengthmax)
              row1_2=screeninfo2.string_formatting(tbuff[1],screeninfo2.waylengthmax)
              t2.add_row([row1_1,row1_2]) 
          print(t2)
          self.close()

      def path_create(self,pn,pw='',pc=''):
          self.path_mod()
          #print(pn)
          if not os.path.exists(pw):
             self.info.Perror()
             exit()
          j=self.db.execute('SELECT * FROM ep WHERE pathway_name=?',(pn,))
          if len(j.fetchall())==0:
             self.db.execute('INSERT INTO ep VALUES(?,?,?)',(pn,pw,pc))
             self.epwdb.commit()
          self.module_create()
          self.close()

      def path_comment(self,pn):
          j=self.db.execute('SELECT * FROM ep WHERE pathway_name=?',(pn,))
          if len(j.fetchall())!=0:
             print("Pathway name: "+pn+"\n")
             print("Exsits comment:\n")
             for row in self.db.execute('SELECT * FROM ep WHERE pathway_name=?',(pn,)):
                 print(row[2])
             pc=input("New comment (Ended by Enter):\n")
             self.db.execute('UPDATE ep SET comment=? WHERE pathway_name=?',(pc,pn))
             self.epwdb.commit() 
          else:
             self.info.Pderror()
          self.close()

      def path_modify(self,pn,pw):
          if not os.path.exists(pw):
             self.info.Perror()
             self.epwdb.close()
          else:
             j=self.db.execute('SELECT * FROM ep WHERE pathway_name=?',(pn,))
             if len(j.fetchall())!=0:
                self.db.execute('UPDATE ep SET folder_path=? WHERE pathway_name=?',(pw,pn))
                self.epwdb.commit()
             else:
                self.info.Pderror()
             self.module_create()
             self.close()

      def path_delete(self,pn):
          self.dbdelete(pn)
          self.module_create()
          self.close()

      def cmodfile(self):
          if not os.path.isfile(self.module_file):
             self.module_create()
      
      def path_backup(self):
          self.cmds.module_backup(self.df,self.bf)

      def path_restore(self):
          self.cmds.module_restore(self.bf+'/'+self.dbfile,self.df)
          self.module_create()
          self.close()
      
      def path_uninstall(self):
          self.close()
          self.cmds.uninstall(self.module_name,self.module_file)

