#!/usr/bin/env php
<?php
use AlfredBez\OxidDumpAutoload\{AliasDumper, AliasBuilder, ClassFilter, Config};
use AlfredBez\OxidDumpAutoload\Chain\{ShopChain, MetadataChain};

$dirname = dirname(__FILE__);
$vendorFolder = file_exists($dirname . '/vendor/')
    ? $dirname . '/vendor/'
    : substr($dirname, 0, strpos($dirname, '/vendor/') + 8);
require_once($vendorFolder . 'autoload.php');

$climate = new League\CLImate\CLImate;

$climate->arguments->add([
    'config' => [
        'prefix'       => 'c',
        'longPrefix'   => 'config',
        'description'  => 'Path to custom config file',
        'defaultValue' => '.autoload.oxid.config.json',
    ],
    'source' => [
        'prefix'       => 's',
        'longPrefix'   => 'source',
        'description'  => 'You can specify a source as a classlist. Possible values are: '
        . '"source/modules/myvendor/mymodule/metadata.php" or just "shop" if you want all shop classes',
        'defaultValue' => 'shop',
    ],
    'shopid' => [
        'prefix'       => 'i',
        'longPrefix'   => 'shopid',
        'description'  => 'Set a custom shop-id (works only when source is set to "shop")',
        'defaultValue' => 1,
        'castTo'       => 'int',
    ],
    'filter' => [
        'prefix'       => 'f',
        'longPrefix'   => 'filter',
        'description'  => 'Filters the given classes before creating the aliases. You can add multiple filters '
        . 'seperated by a comma',
    ],
    'path' => [
        'prefix'      => 'p',
        'longPrefix'  => 'path',
        'description' => 'Write output to this path instead of printing to STDOUT',
    ],
    'only-active' => [
        'longPrefix'  => 'only-active',
        'prefix'      => 'a',
        'description' => 'Use only active classes (works only when source is set to "shop")',
        'noValue'     => true,
    ],
    'help' => [
        'longPrefix'  => 'help',
        'prefix'      => 'h',
        'description' => 'Prints a usage statement',
        'noValue'     => true,
    ],
]);

$climate->arguments->parse();
if ($climate->arguments->defined('help')) {
    $climate->usage();
    exit;
}

$arguments = [];
$argumentKeys = ['filter','only-active','shopid','source','path'];
foreach ($argumentKeys as $argumentKey) {
    if ($climate->arguments->defined($argumentKey)) {
        $arguments[$argumentKey] = $climate->arguments->get($argumentKey);
    }
}
$config = new Config($arguments);
try {
    $config->load($climate->arguments->get('config'));
} catch (\InvalidArgumentException $exception) {
    $climate->yellow($exception->getMessage());
} catch (\UnexpectedValueException $exception) {
    $climate->red($exception->getMessage());
    exit;
}

$filterClass = null;
if (is_array($config->get('filter'))) {
    $filterClass = ClassFilter::fromArray($config->get('filter'));
}
if (is_string($config->get('filter')) && strlen($config->get('filter')) > 0) {
    $filterClass = ClassFilter::fromString($config->get('filter'));
}
$aliasBuilder = new AliasBuilder($filterClass);

try {
    if ($config->get('source') === 'shop') {
        $chain = (new ShopChain())->getClassChain($config->get('only-active'), $config->get('shopid'));
    }
    else {
        $chain = (new MetadataChain($config->get('source')))->getClassChain();
    }
} catch (\Throwable $exception) {
    $climate->red($exception->getMessage());
    exit;
}

$dumper = new AliasDumper();
$dump = $dumper->dump($aliasBuilder->buildAliasesFor($chain));
if (strlen($config->get('path')) > 0) {
    file_put_contents($config->get('path'), $dump);
} else {
    echo $dump;
}
