
import os
import sys
import time
import pythonnet
from pythonnet import load
import clr
import System
from System.CodeDom.Compiler import CodeDomProvider, CompilerParameters

# --- Configuration to Test ---
SERVERS = [
    "rithmic.com:80",
    "www.rithmic.com:80",
    "ritpz01000.01.rithmic.com:56000",
    "ritpz01000.01.rithmic.com:65000",
    "ritpz05001.rithmic.com:56000",
    "ritpz05001.rithmic.com:65000",
    "paper.rithmic.com:80",
]

# --- Setup Pythonnet ---
libs_dir = os.path.join(os.getcwd(), "libs")
if not os.path.exists(libs_dir):
    libs_dir = os.path.join(os.path.dirname(os.path.dirname(os.getcwd())), "libs")

sys.path.append(libs_dir)
if hasattr(os, "add_dll_directory"):
    os.add_dll_directory(libs_dir)

dll_path = os.path.join(libs_dir, "rapiplus.dll")
clr.AddReference("rapiplus")
import com.omnesys.rapi as rapi

# --- C# Wrapper Compilation ---
def compile_wrapper():
    csharp_code = """
    using System;
    using com.omnesys.rapi;

    namespace RithmicBridge.EnvWrapper
    {
        public class EnvAdmCallbacks : AdmCallbacks
        {
            public Action<EnvironmentInfo> OnEnvironment;

            public override void Alert(AlertInfo oInfo) {}
            public override void EnvironmentList(EnvironmentListInfo oInfo) {}
            public override void Environment(EnvironmentInfo oInfo) { if (OnEnvironment != null) OnEnvironment(oInfo); }

            public override bool Equals(object obj) { return base.Equals(obj); }
            public override int GetHashCode() { return base.GetHashCode(); }
            public override string ToString() { return base.ToString(); }
        }
    }
    """
    provider = CodeDomProvider.CreateProvider("CSharp")
    params = CompilerParameters()
    params.GenerateInMemory = True
    params.ReferencedAssemblies.Add("System.dll")
    params.ReferencedAssemblies.Add(dll_path)
    
    results = provider.CompileAssemblyFromSource(params, csharp_code)
    if results.Errors.HasErrors:
        print("Compilation Errors:")
        for error in results.Errors:
            print(f"  {error.ErrorText}")
        return None
    return results.CompiledAssembly

def main():
    assembly = compile_wrapper()
    if not assembly:
        return

    t_adm = assembly.GetType("RithmicBridge.EnvWrapper.EnvAdmCallbacks")
    t_env_info = rapi.EnvironmentInfo
    
    for server in SERVERS:
        print(f"=== Testing Domain Server: {server} ===")
        
        adm_cb = System.Activator.CreateInstance(t_adm)
        
        # Callback
        def _on_environment(info):
            print(f"  [ENV FOUND] Key: {info.EnvKey}, Desc: {info.Description}")

        adm_cb.OnEnvironment = System.Action[t_env_info](_on_environment)

        params = rapi.REngineParams()
        params.AppName = "GetEnvList"
        params.AppVersion = "1.0.0"
        params.AdmCallbacks = adm_cb
        params.LogFilePath = os.path.abspath(f"env_list_{server.replace(':', '_')}.log")
        params.DmnSrvrAddr = server
        # DomainName/LicSrvrAddr shouldn't matter for just getting env list via DmnSrvrAddr?
        # But required fields need some value.
        params.DomainName = "Rithmic Paper Trading" 
        params.LicSrvrAddr = server
        params.LocBrokAddr = server
        params.LoggerAddr = server

        try:
            engine = rapi.REngine(params)
            print("  -> REngine Instantiation: SUCCESS")
            print("  Waiting 5s for Env callbacks...")
            time.sleep(5)
            engine.shutdown()
        except Exception as e:
            print(f"  -> REngine Instantiation: FAILED ({e})")
        
        print("-" * 40)

if __name__ == "__main__":
    main()
