#!/usr/bin/env php
<?php

use Dotenv\Dotenv;
use Dotenv\Environment\Adapter\EnvConstAdapter as V3EnvConstAdapter;
use Dotenv\Environment\Adapter\ServerConstAdapter as V3ServerConstAdapter;
use Dotenv\Environment\DotenvFactory;
use Dotenv\Repository\Adapter\EnvConstAdapter as V4orV5EnvConstAdapter;
use Dotenv\Repository\Adapter\ServerConstAdapter as V4orV5ServerConstAdapter;
use Dotenv\Repository\RepositoryBuilder;
use Illuminate\Container\Container;
use Laravel\VaporCli\Application;
use Laravel\VaporCli\Commands;

/**
 * Require the autoloader.
 */
if (file_exists(__DIR__.'/../../autoload.php')) {
    require __DIR__.'/../../autoload.php';
} else {
    require __DIR__.'/vendor/autoload.php';
}

/**
 * Load the environment variables.
 */
(function () {
    if (class_exists(RepositoryBuilder::class)) {
        $adapters = [
            V4orV5EnvConstAdapter::class,
            V4orV5ServerConstAdapter::class,
        ];

        if (method_exists(RepositoryBuilder::class, 'addReader')) { // V5
            $repository = RepositoryBuilder::createWithNoAdapters();

            foreach ($adapters as $adapter) {
                $repository = $repository
                    ->addReader($adapter)
                    ->addWriter($adapter);
            }
        } else { // V4
            $adapters = array_map(function ($adapterClass) {
                return new $adapterClass();
            }, $adapters);

            $repository = RepositoryBuilder::create()
                ->withReaders($adapters)
                ->withWriters($adapters);
        }

        Dotenv::create(
            $repository->immutable()->make(),
            __DIR__
        )->safeLoad();
    } else { // V3
        Dotenv::create(__DIR__, null, new DotenvFactory([
            new V3EnvConstAdapter, new V3ServerConstAdapter,
        ]))->safeLoad();
    }
})();

/**
 * Create the container instance.
 */
Container::setInstance($container = new Container);

/**
 * Start the console application.
 */
$app = new Application('Laravel Vapor', '1.42.0');

// Authentication...
$app->add(new Commands\LoginCommand);

// Teams...
$app->add(new Commands\TeamListCommand);
$app->add(new Commands\TeamCommand);
$app->add(new Commands\TeamCurrentCommand);
$app->add(new Commands\TeamSwitchCommand);
$app->add(new Commands\MemberListCommand);
$app->add(new Commands\MemberAddCommand);
$app->add(new Commands\MemberRemoveCommand);
$app->add(new Commands\FireCommand);

// Providers...
$app->add(new Commands\ProviderListCommand);
$app->add(new Commands\ProviderCommand);
$app->add(new Commands\ProviderUpdateCommand);
$app->add(new Commands\ProviderDeleteCommand);

// Zones...
$app->add(new Commands\ZoneListCommand);
$app->add(new Commands\ZoneCommand);
$app->add(new Commands\ZoneDeleteCommand);

// Records...
$app->add(new Commands\RecordListCommand);
$app->add(new Commands\RecordCommand);
$app->add(new Commands\RecordDeleteCommand);

// Certificates...
$app->add(new Commands\CertListCommand);
$app->add(new Commands\CertCommand);
$app->add(new Commands\CertValidateCommand);
$app->add(new Commands\CertDeleteCommand);

// Networks...
$app->add(new Commands\NetworkListCommand);
$app->add(new Commands\NetworkCommand);
$app->add(new Commands\NetworkShowCommand);
$app->add(new Commands\NetworkNatCommand);
$app->add(new Commands\NetworkDeleteNatCommand);
$app->add(new Commands\NetworkDeleteCommand);

// Databases...
$app->add(new Commands\DatabaseListCommand);
$app->add(new Commands\DatabaseCommand);
$app->add(new Commands\DatabaseShowCommand);
$app->add(new Commands\DatabaseScaleCommand);
$app->add(new Commands\DatabasePasswordCommand);
$app->add(new Commands\DatabaseProxyCommand);
$app->add(new Commands\DatabaseDeleteProxyCommand);
$app->add(new Commands\DatabaseRestoreCommand);
$app->add(new Commands\DatabaseMetricsCommand);
$app->add(new Commands\DatabaseUpgradeCommand);
$app->add(new Commands\DatabaseUsersCommand);
$app->add(new Commands\DatabaseUserCommand);
$app->add(new Commands\DatabaseDropUserCommand);
$app->add(new Commands\DatabaseShellCommand);
$app->add(new Commands\DatabaseTunnelCommand);
$app->add(new Commands\DatabaseDeleteCommand);

// Caches...
$app->add(new Commands\CacheListCommand);
$app->add(new Commands\CacheCommand);
$app->add(new Commands\CacheShowCommand);
$app->add(new Commands\CacheScaleCommand);
$app->add(new Commands\CacheMetricsCommand);
$app->add(new Commands\CacheTunnelCommand);
$app->add(new Commands\CacheDeleteCommand);

// Jumpboxes...
$app->add(new Commands\JumpListCommand);
$app->add(new Commands\JumpCommand);
$app->add(new Commands\JumpDeleteCommand);

// Balancers...
$app->add(new Commands\BalancerListCommand);
$app->add(new Commands\BalancerCommand);
$app->add(new Commands\BalancerDeleteCommand);

// Projects...
$app->add(new Commands\InitCommand);
$app->add(new Commands\UiCommand);
$app->add(new Commands\ProjectDeleteCommand);
$app->add(new Commands\ProjectDescribeCommand);
$app->add(new Commands\ProjectListCommand);

// Environments...
$app->add(new Commands\EnvListCommand);
$app->add(new Commands\EnvCommand);
$app->add(new Commands\EnvDescribeCommand);
$app->add(new Commands\EnvPullCommand);
$app->add(new Commands\EnvPushCommand);
$app->add(new Commands\EnvCloneCommand);
$app->add(new Commands\EnvDeleteCommand);
$app->add(new Commands\OpenCommand);

// Vanity Domains...
$app->add(new Commands\VanityDomainDeleteCommand);

// Secrets
$app->add(new Commands\SecretListCommand);
$app->add(new Commands\SecretCommand);
$app->add(new Commands\SecretPassportCommand);
$app->add(new Commands\SecretDeleteCommand);

// Deployments...
$app->add(new Commands\DeployListCommand);
$app->add(new Commands\BuildCommand);
$app->add(new Commands\DeployCommand);
$app->add(new Commands\RedeployCommand);
$app->add(new Commands\HookLogCommand);
$app->add(new Commands\HookOutputCommand);

// Rollbacks / Maintenance Mode...
$app->add(new Commands\RollbackCommand);
$app->add(new Commands\DownCommand);
$app->add(new Commands\UpCommand);

// Commands / Invocations...
$app->add(new Commands\CommandCommand);
$app->add(new Commands\CommandLogCommand);
$app->add(new Commands\CommandAgainCommand);
$app->add(new Commands\TinkerCommand);

// Logs...
$app->add(new Commands\TailCommand);

// Metrics...
$app->add(new Commands\MetricsCommand);

// Docker...
$app->add(new Commands\LocalCommand);
$app->add(new Commands\TestCommand);

// Assets...
$app->add(new Commands\InvalidateAssetCacheCommand);

$app->run();
