#!/usr/bin/env python

import glob
import os
import random
import sys
from threading import Lock
import time

from aman.com import AircraftReport_pb2
from aman.com.Euroscope import Euroscope
from aman.com.Weather import Weather
from aman.config.AircraftPerformance import AircraftPerformance
from aman.config.Airport import Airport
from aman.config.System import System
from aman.sys.Worker import Worker

class AMAN:
    def findConfigPath():
        envvar = os.environ.get('AMAN_CONFIG_PATH')
        if None == envvar:
            print('No AMAN_CONFIG_PATH in environment variables found. Using execution directory.')
            path = os.getcwd()
        else:
            print('AMAN_CONFIG_PATH found.')
            path = envvar

        print('Config-path: ' + path)
        return path

    def __init__(self):
        # default initialization of members
        configPath = AMAN.findConfigPath()
        self.SystemConfig = None
        self.AircraftPerformance = None
        self.Receiver = None
        self.Weather = None
        self.WebUi = None
        self.Workers = []
        self.WorkersLock = Lock()

        # read all system relevant configuration files
        self.SystemConfig = System(os.path.join(configPath, 'System.ini'))
        print('Parsed System.ini')

        # read the aircraft performance data
        self.AircraftPerformance = AircraftPerformance(os.path.join(configPath, 'PerformanceData.ini'))
        if None == self.AircraftPerformance:
            sys.stderr.write('No aircraft performance data found!')
            sys.exit(-1)
        else:
            print('Parsed PerformanceData.ini. Extracted ' + str(len(self.AircraftPerformance.Aircrafts)) + ' aircrafts')

        # create the communication syb
        self.Weather = Weather(self.SystemConfig.Weather)
        self.Receiver = Euroscope(configPath, self.SystemConfig.Server, self)

        self.acquireLock()

        # find the airport configurations and create the workers
        airportsPath = os.path.join(os.path.join(configPath, 'airports'), '*.ini')
        for file in glob.glob(airportsPath):
            icao = os.path.splitext(os.path.basename(file))[0]

            print('Parsing planner configuration for ' + icao)
            airportConfig = Airport(file, icao)

            # initialize the worker thread
            worker = Worker(icao, airportConfig, self.Weather, self.AircraftPerformance, self.Receiver)
            self.Workers.append(worker)
            print('Started worker for ' + icao)

        self.releaseLock()

        # initialize the random number generator
        random.seed(time.time())

    def acquireLock(self):
        if None != self.WorkersLock:
            self.WorkersLock.acquire()

    def releaseLock(self):
        if None != self.WorkersLock:
            self.WorkersLock.release()

    def updateAircraftReport(self, report : AircraftReport_pb2.AircraftReport):
        self.acquireLock()

        # find the correct worker for the inbound
        for worker in self.Workers:
            if worker.Icao == report.destination:
                worker.acquireLock()
                worker.ReportQueue[report.aircraft.callsign] = report
                worker.releaseLock()
                break

        self.releaseLock()

    def findAirport(self, icao : str):
        self.acquireLock()

        airport = None
        for worker in self.Workers:
            if icao == worker.Icao:
                airport = worker
                break

        self.releaseLock()

        return airport
