#!/usr/bin/env php
<?php
/**
 * @license  http://www.apache.org/licenses/LICENSE-2.0
 *           Copyright [2012] [Robert Allen]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * This is more intended as an example than anything else however it does
 * provide functionality to generate the json files as static entities as part
 * of a deployment process etc.
 */
function includeIfExists($file)
{
    if (file_exists($file)) {
        return include $file;
    }
}

if ((!$loader = includeIfExists(__DIR__ . '/../vendor/autoload.php'))
    && (!$loader = includeIfExists(__DIR__ . '/../../../autoload.php'))
    && (!$loader = includeIfExists('vendor/autoload.php'))
) {
    die(<<<'EOT'
You must set up the project dependencies, run the following commands:
wget http://getcomposer.org/composer.phar
php composer.phar install

EOT
    );
}
$shortopts = 'fp:hvo:i:e:';

$longopts = array(
    'project-dir:',
    'exclude-path:',
    'include-path:',
    'output-dir',
    'format'
);
$prettyPrint = false;
try {
    $options = getopt($shortopts, $longopts);

    if (isset($options['v']) || isset($options['version'])) {
        echo <<<EOF
Swagger-PHP Version: 0.4.0

EOF;
        exit;
    }
    if (isset($options['h']) || isset($options['help'])) {
        echo <<<EOF

Usage: swagger --project-path PATH [--output-path PATH]...
    Generate Swagger JSON documents for a project.
        Mandatory argument[s]:
            -p, --project-path    base path of the project to perform swagger discovery
        Optional arguments:
            -e, --exclude-path    Optional exclude path
                                    ex: --exclude-path vendor:library/Zend:library/Foo
            -i, --include-path    Optional bootstrap file for additional include path support
                                    ex: --include-path Zend:/usr/local/share/pear
            -o, --output-path     directory to store the generated json documents
            -f, --format          format JSON output in readable formatting.
            -h, --help            generates this help message
            -v, --version         Swagger-PHP version


EOF;
        exit;
    }
    if (isset($options['e']) || isset($options['exclude-path'])) {
        $excludePath = isset($options['e']) ? $options['e'] : $options['exclude-path'];
        $excludePaths = explode(':', $excludePath);
        foreach ($excludePaths as $index => $excludePath) {
            if (DIRECTORY_SEPARATOR != substr($excludePath, 0, 1)) {
                $excludePaths[$index] = getcwd() . DIRECTORY_SEPARATOR . $excludePath;
            }
        }
        $excludePath = implode(':', $excludePaths);
    }
    if ((isset($options['i']) && ($bootstrap = $options['i']))
        || (isset($options['include-path']) && ($bootstrap = $options['include-path']))
    ) {
        /* @var  \Composer\Autoload\ClassLoader $loader */
        foreach (explode(',', $bootstrap) as $incPath) {
            @list($namespace, $inclusionPath) = explode(':', $incPath);
            $loader->add($namespace, array($inclusionPath ? : '.'));
            if (!$inclusionPath && is_file($incPath)) {
                require_once($incPath);
            }
        }
    }
    if (!isset($options['p']) && !isset($options['project-dir'])) {
        throw new RuntimeException('--project-dir must be provided');
    } else {
        if (isset($options['project-dir'])
            && !empty($options['project-dir'])
        ) {
            $projectPath = $options['project-dir'];
        } else {
            $projectPath = $options['p'];
        }
    }
    $outputPath = null;
    if (!isset($options['output-dir']) && !empty($options['output-dir'])) {
        $outputPath .= $options['output-dir'] . DIRECTORY_SEPARATOR;
    } elseif (isset($options['o']) && !empty($options['o'])) {
        $outputPath .= $options['o'] . DIRECTORY_SEPARATOR;
    } else {
        $outputPath = getcwd() . DIRECTORY_SEPARATOR;
    }
    if (isset($options['f']) || isset($options['format'])) {
        $prettyPrint = true;
    }
    $swagger = \Swagger\Swagger::discover($projectPath, isset($excludePath) ? $excludePath : null);
    $resourceName = false;
    $output = array();
    foreach ($swagger->getResourceNames() as $resourceName) {
        $json = $swagger->getResource($resourceName, $prettyPrint);
        $resourceName = str_replace(DIRECTORY_SEPARATOR, '-', ltrim($resourceName, DIRECTORY_SEPARATOR));
        $output[$resourceName] = $json;
    }
    if ($output) {
        if (file_exists($outputPath) && !is_dir($outputPath)) {
            throw new RuntimeException(
                sprintf('[%s] is not a directory', $outputPath)
            );
        } else {
            if (!file_exists($outputPath) && !mkdir($outputPath, '0755', true)) {
                throw new RuntimeException(
                    sprintf('[%s] is not writeable', $outputPath)
                );
            }
            if (!file_exists($outputPath . DIRECTORY_SEPARATOR . 'resources') &&
                !mkdir($outputPath . DIRECTORY_SEPARATOR . 'resources', '0755', true)) {
                throw new RuntimeException(
                    sprintf('[%s] is not writeable', $outputPath . DIRECTORY_SEPARATOR . 'resources')
                );
            }
        }
        if (file_put_contents($outputPath . 'api-docs.json', $swagger->getResourceList($prettyPrint))) {
            echo $outputPath . 'api-docs.json created', PHP_EOL;
        }
        foreach ($output as $name => $json) {
            $name = DIRECTORY_SEPARATOR . str_replace(DIRECTORY_SEPARATOR, '-', ltrim($name, DIRECTORY_SEPARATOR));
            echo $outputPath . $name . '.json created', PHP_EOL;
            file_put_contents(
                $outputPath . DIRECTORY_SEPARATOR . 'resources'. DIRECTORY_SEPARATOR . $name . '.json',
                $json
            );
        }
    } else {
        echo 'no valid resources found', PHP_EOL;
    }
} catch (Exception $e) {
    echo 'An Error has occured:', PHP_EOL;
    echo (string)$e->getMessage(), PHP_EOL;
}
