import clr
import System

import sys
from configparser import ConfigParser
from pathlib import Path

# read configuration file
config_file = 'config.ini'
config = ConfigParser()
config.read(config_file)

# get paths
vl_path = config['paths']['virtuallab']
if not Path(vl_path).exists():
    raise NotADirectoryError('No or incorrect VirtualLab installation path detected! Please check the config.ini!')
if not Path(vl_path).is_dir():
    raise NotADirectoryError('VirtualLab installation path is not a directory! Please check the config.ini!')

# get global settings
use_multicore = int(config['globals']['use_multicore'])
number_of_cores = int(config['globals']['number_of_cores'])

# Append directories to look for modules to your vl installation
sys.path.append(vl_path)


# Function for resolving problems with programmable components
def __add_assembly_redirect():
    # See https://github.com/pythonnet/pythonnet/issues/832
    def assembly_resolve(app_domain, resolve_event_args):
        name = resolve_event_args.Name.split(',')[0]
        try:
            return next(x for x in app_domain.GetAssemblies() if x.GetName().Name == name)
        except StopIteration:
            pass
    System.AppDomain.CurrentDomain.AssemblyResolve += assembly_resolve
    

# Add reference for solving issues with programmable components
clr.AddReference('System.Runtime.CompilerServices.Unsafe')
__add_assembly_redirect()

# Add reference to VirtualLabAPI (from vl_path) for Common Language Runtime (CLR)
clr.AddReference('VirtualLabAPI')
clr.AddReference('VirtualLab.Programming')


# Import modules needed for simulation
from VirtualLabAPI.Core.LightPath import Lightpath, DetectorResultObject
from VirtualLabAPI.Core.Common import Globals, GlobalOptions, IDocument
from VirtualLabWrapperAPI.Wrapper import LightPathDiagramWrapper
from VirtualLabAPI.Core.Numerics import PhysicalProperty, PhysicalUnits, Complex
from VirtualLabAPI.Core.ExportImport import LightPathExportImportSupport
from VirtualLabAPI.Core.SimulationWrappers import DataDisplayToNull

# Forward log-messages to a new window in order to avoid NullReference-Exception
Globals.DataDisplay = DataDisplayToNull()

# Append path for VL snippet editor to look for modules
Globals.ProgrammableDLLSupportPathInternal = vl_path

# Initialize Global Options of VLF
GlobalOptions.Initialize()

# Multi-core stuff
Globals.Defaults.UseMultipleCores = bool(use_multicore)
Globals.Defaults.NumberOfCoresToUse = number_of_cores
