<?php declare(strict_types=1);

namespace App\Controller;

error_reporting(error_level: E_ALL);

use App\Repository\DomainRepository;
use App\Repository\DynDNSRepository;
use DI\Container;
use DI\ContainerBuilder;
use DI\DependencyException;
use DI\NotFoundException;
use Exception;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
use Monolog\Logger;
use function DI\autowire;

/**
 *
 */
class BindAPI
{
	private Logger $logger;
	private Container $container;

	/**
	 * @throws Exception
	 */
	public function __construct(bool $quiet)
	{
		// init the logger
		$dateFormat = "Y:m:d H:i:s";
		$output = "%datetime% %channel%.%level_name% %message%\n"; // %context% %extra%
		$formatter = new LineFormatter(format: $output, dateFormat: $dateFormat);
		
		$debug = (new ConfigController(quiet: $quiet))->getConfig(configKey: 'debug');
		if ($debug) {
			$stream = new StreamHandler(stream: dirname(path: __DIR__, levels: 2) . '/bindAPI.log', level: Level::Debug);
		} else {
			$stream = new StreamHandler(stream: dirname(path: __DIR__, levels: 2) . '/bindAPI.log', level: Level::Info);
		}
		$stream->setFormatter(formatter: $formatter);
		
		$this->logger = new Logger(name: 'bindAPI');
		$this->logger->pushHandler(handler: $stream);
		$this->logger->debug(message: 'bindAPI started');
		
		
		$containerBuilder = new ContainerBuilder();
		$containerBuilder->addDefinitions([
			ConfigController::class => autowire()
                ->constructorParameter(parameter: 'quiet', value: $quiet),
			CLIController::class      => autowire()
				->constructorParameter(parameter: 'logger', value: $this->logger)
                ->constructorParameter(parameter: 'quiet', value: $quiet),
            DomainController::class   => autowire()
				->constructorParameter(parameter: 'logger', value: $this->logger)
                ->constructorParameter(parameter: 'quiet', value: $quiet),
            DomainRepository::class   => autowire()
				->constructorParameter(parameter: 'logger', value: $this->logger),
			DynDnsRepository::class  => autowire()
				->constructorParameter(parameter: 'logger', value: $this->logger),
			RequestController::class => autowire()
				->constructorParameter(parameter: 'logger', value: $this->logger)
		]);
		$this->container = $containerBuilder->build();
	}
	
	
	/**
	 * @throws DependencyException
	 * @throws NotFoundException
	 */
	public function runCommand(array $arguments): void
	{
		$this->logger->debug(message: 'runCommand()');
		$cliController = $this->container->get(name: CLIController::class);
		$cliController->runCommand(arguments: $arguments);
	}
	
	
	/**
	 * @throws DependencyException
	 * @throws NotFoundException
	 */
	public function handleRequest(string $requestMethod, array $uri): void
	{
		$this->logger->debug(message: 'handleRequest()');
		$requestController = $this->container->get(name: RequestController::class);
		$requestController->handleRequest(requestMethod: $requestMethod, uri: $uri);
	}
}
