#!/usr/bin/env python

import glob
import os
import random
import sys
import time

from aman.com import AircraftReport_pb2
from aman.com.Euroscope import Euroscope
from aman.com.Weather import Weather
from aman.com.WebUI import WebUI
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
        self.SystemConfig = None
        self.AircraftPerformance = None
        self.Receiver = None
        self.Weather = None
        self.WebUi = None
        self.Workers = []

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

    def __del__(self):
        self.release()

    def aquire(self):
        configPath = AMAN.findConfigPath()

        # 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')

        self.Weather = Weather()
        self.Weather.acquire(self.SystemConfig.Weather)
        self.WebUi = WebUI()
        self.WebUi.acquire(self.SystemConfig.Server, self)

        # create the EuroScope receiver
        self.Receiver = Euroscope()

        # 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()
            worker.acquire(icao, airportConfig, self.Weather, self.AircraftPerformance, self.WebUi, self.Receiver)
            self.Workers.append(worker)
            print('Started worker for ' + icao)

        # initialize the receiver
        self.Receiver.acquire(configPath, self.SystemConfig.Server, self)

    def release(self):
        if None != self.Workers:
            for worker in self.Workers:
                worker.release()
        self.Workers = None

        if None != self.Receiver:
            self.Receiver.release()
        self.Receiver = None

        if None != self.Weather:
            self.Weather.release()
        self.Weather = None

        if None != self.WebUi:
            self.WebUi.release()
        self.WebUi = None

    def updateAircraftReport(self, report : AircraftReport_pb2.AircraftReport):
        # 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