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

namespace Cougar\PDO;

use Cougar\Util\Arc4;
use Cougar\Util\Config;

/**
 * Prompts the user for the database connection information and generates a
 * new connection file.
 *
 * @history
 * 2013.09.30:
 *   (AT)  Initial release
 *
 * @version 2013.09.30
 * @package Cougar
 * @license MIT
 *
 * @author (AT) Alberto Trevino, Brigham Young Univ. <alberto@byu.edu>
 */

# Make sure we are running in a CLI environment
if (PHP_SAPI !== "cli")
{
    echo("This program must be run from the command line\n");
    exit(1);
}

# Initialize the framework
require_once(__DIR__ . "/../../cougar.php");


echo("\n");
echo("How would you like to protect the password?

    1. With Obfuscation (no key required)
    2. With ARC4; I'll enter the encryption key manually
    3. With ARC4; the encryption key is stored in a file\n\n");

$use_obfuscation = false;
$arc4_filename = null;
switch(getUserInput("Encryption key source", range(1, 3)))
{
    case "1":
        echo("\n");
        $use_obfuscation = true;
        break;
    case "2":
        echo("\n");
        $enc_key = "";
        while (! $enc_key)
        {
            try
            {
                $enc_key = getUserInput(
                    "Please enter the encryption key in hex");
                
                # Make sure the key is valid
                Arc4::setKey($enc_key);
            }
            catch(\Exception $e)
            {
                echo("  Invalid key!\n");
            }
            try
            {
                $magic = getUserInput("Enter the encryption MAGIC value");

                # Make sure the key is valid
                Arc4::setMagic($magic);
            }
            catch(\Exception $e)
            {
                echo("  Invalid magic value!\n");
            }

            # Set teh ARC4 parameters
            Arc4::setKey($enc_key);
            Arc4::setMagic($magic);
            Arc4::useCompression(true);
        }
        break;
    case "3":
        echo("\n");
        $enc_key = false;
        while(! $enc_key)
        {
            $arc4_filename = getUserInput(
                "Please enter the path of the ARC4 configuration file");

            if (! file_exists($arc4_filename))
            {
                echo("  File does not exist!\n");
            }
            else
            {
                try
                {
                    $slash_pos = strrpos($arc4_filename, "/");
                    if ($slash_pos !== false)
                    {
                        $path = substr($arc4_filename, 0, $slash_pos);
                        $arc4_filename = substr($arc4_filename, $slash_pos + 1);
                        Config::$subdirList[] = $path;
                    }

                    # Load the ARC4 parameters
                    ARC4::loadParameters($arc4_filename);
                    $enc_key = true;


                }
                catch (\Exception $e)
                {
                    echo("  Error loading encryption file\n");
                }
            }
        }
        break;
}


echo("\n");
echo("Please select the application environment:

    1. Local
    2. Development
    3. Test
    4. Stage
    5. Debug
    6. Production
    7. Default (no environment name)
    8. Other\n\n");

switch(getUserInput("Environment", range(1, 8)))
{
    case "1":
        $environment = "local";
        break;
    case "2":
        $environment = "development";
        break;
    case "3":
        $environment = "test";
        break;
    case "4":
        $environment = "stage";
        break;
    case "5":
        $environment = "debug";
        break;
    case "6":
        $environment = "production";
        break;
    case "7":
        $environment = "";
        break;
    case "8":
        $environment = getUserInput("Environment name");
        break;
}


echo("Please select the type of database that will be used:

    1. Oracle
    2. MySQL
    3. SQLite
    4. PostgreSQL
    5. Microsoft SQL Server
    6. ODBC
    7. Other\n\n");

switch(getUserInput("Database type", range(1,7)))
{
    case "1":
        $db = "";
        while (! $db)
        {
            $db = getUserInput(
                "Enter the name of the database (or //hostname:port/schema)");
        }
        $dsn = "oci:dbname=" . $db;
        break;
    case "2":
        $hostname = "";
        while (! $hostname)
        {
            $hostname = getUserInput("Enter the MySQL server hostname");
        }
        $db = "";
        while (! $db)
        {
            $db = getUserInput("Enter the name of the database (schema)");
        }
        $dsn = "mysql:host=" . $hostname . ";dbname=" . $db;
        break;
    case "3":
        $db = "";
        while (! $db)
        {
            $db = getUserInput("Enter the full path to the database file " .
                "(or :memory: for in-memory database)");
        }
        $dsn = "sqlite:" . $db;
        break;
    case "4":
        $hostname = "";
        while (! $hostname)
        {
            $hostname = getUserInput("Enter the PostreSQL server hostname");
        }
        $db = "";
        while (! $db)
        {
            $db = getUserInput("Enter the name of the database (schema) name");
        }
        $dsn = "pgsql:host=" . $hostname . ";dbname=" . $db;
        break;
    case "5":
        $hostname = "";
        while (! $hostname)
        {
            $hostname = getUserInput("Enter the SQL Server hostname");
        }
        $db = "";
        while (! $db)
        {
            $db = getUserInput("Enter the name of the database (schema) name");
        }
        $dsn = "sqlsrv:Server=" . $hostname . ";Database=" . $db .
            "encrypt=1;ConnectionPooling=1";
        break;
    case "6":
        $db = "";
        while (! $db)
        {
            $db = getUserInput("Enter the driver manager database name " .
                "or uncataloged connection string");
        }
        $dsn = "odbc:d" . $db;
        break;
    case "7":
        $dsn = "";
        while (! $dsn)
        {
            $dsn = getUserInput("Enter the full PDO DSN connection string");
        }
        break;
}


echo("\n");
$username = "";
while (! $username)
{
    $username = getUserInput("Enter the username");
}
$password = getUserInput("Enter the password");

echo("\n");
echo("Use persistent connections (recommended for Oracle only)?

    1. No
    2. Yes\n\n");

switch(getUserInput("Persistent connection", range(1,2)))
{
    case 1:
        $persistent = false;
        break;
    case 2:
        $persistent = true;
        break;
}

echo("\n");
$connection_name = "";
while (! $connection_name)
{
    $connection_name = getUserInput("Enter the name of this connection");
}

/* End of user input code */

if ($use_obfuscation)
{
    $encoding = "Obfuscation";
}
else
{
    # Set the ARC4 parameters
    $encoding = "Arc4";
}

# Create the file
$filename = PDOFactory::createConnectionFile($connection_name, $environment,
    $dsn, $username, $password, $encoding, $arc4_filename, $persistent);
echo("\nConnection file " . $filename . " has been created.\n");


/* Script functions */

# Define a function to grab user input and optionally validate the value
function getUserInput($prompt = "", array $values = null)
{
    # Display the prompt
    echo($prompt . ": ");
    
    # Get the value
    $value = trim(fgets(STDIN));
    
    # See if we are validating values
    if (is_array($values))
    {
        if (count($values) > 0)
        {
            if (in_array($value, $values))
            {
                # Value matches; return value
                return $value;
            }
            else
            {
                # Value does not match; ask again
                return getUserInput($prompt, $values);
            }
        }
        else
        {
            # Values array given, but no values
            return $value;
        }
    }
    else
    {
        # No values given
        return $value;
    }
}
?>
