# -*- coding: utf-8 -*-
"""
Created on Wed May 23 15:46:11 2018

@author: Lonnie Chrisman
(c) 2018 Lumina Decision System, all rights reserved.

This code is distributed under the MIT gnu license. 
"""

import sys
import win32com
import pythoncom
import comtypes
import winreg
import win32api
import os
from time import sleep
import win32com.server.policy as policy

gCOMServerClasses = []

def AddCOMClass(theClass):
    if not(theClass in gCOMServerClasses):
        gCOMServerClasses.append(theClass)
    
gTopLevelFile = __file__
    
def DoRegServer(theClass):
    global gTopLevelFile
    from comtypes.server.register import UseCommandLine
    print("Registering class " + theClass.__name__ + " as " + theClass._reg_progid_)
    UseCommandLine(theClass)
    # UseCommandLine doesn't set the required registry settings. Add in the one's it lacks:
    sPythonCOM = "CLSID\\" + theClass._reg_clsid_ + "\\PythonCOM"
    keyPythonCOM = winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, sPythonCOM )    
    winreg.SetValue( keyPythonCOM, "", winreg.REG_SZ, theClass._reg_class_spec_ )
    sLocalServer32 = "CLSID\\" + theClass._reg_clsid_ + "\\LocalServer32"
    keyLocalServer32 = winreg.CreateKey(winreg.HKEY_CLASSES_ROOT, sLocalServer32)
    winreg.SetValue( keyLocalServer32, "", winreg.REG_SZ, "\"" + sys.executable + "\" \"" + os.path.abspath(gTopLevelFile) + "\"" )

def DoUnregServer(theClass):
    from comtypes.server.register import UseCommandLine
    print("Unregistering " + theClass._reg_progid_)
    sPythonCOM = "CLSID\\" + theClass._reg_clsid_ + "\\PythonCOM"
    sLocalServer32 = "CLSID\\" + theClass._reg_clsid_ + "\\LocalServer32"
    winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, sPythonCOM)
    winreg.DeleteKey(winreg.HKEY_CLASSES_ROOT, sLocalServer32)
    UseCommandLine(theClass)
    
def serveIt():
    from win32com.server import localserver
    print("Listening...")
    localserver.serve([theClass._reg_clsid_ for theClass in gCOMServerClasses])

def Listen():
    global gBreakPump
    gBreakPump = False
    while not(gBreakPump) and pythoncom.PumpWaitingMessages()==0:
        sleep(0.05)

gFactories = []
       
def startServe(clsids):
    from win32com.server import factory
    global gFactories
    gFactories = factory.RegisterClassFactories(clsids)

    pythoncom.EnableQuitMessage(win32api.GetCurrentThreadId())	
    pythoncom.CoResumeClassObjects()

def stopServe():
    from win32com.server import factory
    global gFactories
    factory.RevokeClassFactories( gFactories )	
    gFactories = []
    pythoncom.CoUninitialize()

def StopServe():
    stopServe()

def Start():
    startServe([theClass._reg_clsid_ for theClass in gCOMServerClasses])

def TopLevelServer(file):
    global gTopLevelFile
    gTopLevelFile = file
    if '/regserver' in sys.argv[1:]:
        for theClass in gCOMServerClasses:
            DoRegServer(theClass)
        # To do: Set clsid\PythonCOM = module.AnalyticaPythonConnector
        # launch params?
    elif '/unregserver' in sys.argv[1:]:
        for theClass in gCOMServerClasses:
            DoUnregServer(theClass)
    else:
        serveIt()

   
