<?php

/**
 * Loads an environment variable
 *
 * @param string $name
 * @param mixed|null $def
 * @param  bool  $local
 * @return array|mixed|string|null
 */
function env(string $name, $def = null, bool $local = false) {
    $value = getenv($name, $local);
    if ($value) {
        return parse_raw_value($value);
    }
    return $def;
}

/**
 * Parses and filters values coming from environment or shell variables.
 *
 * @param $value
 * @return bool|mixed|string|void
 */
function parse_raw_value($value) {
    $value = trim($value);

    switch (strtolower($value)) {
        case 'true':
        case '(true)':
            return true;
        case 'false':
        case '(false)':
            return false;
        case 'empty':
        case '(empty)':
            return '';
        case 'null':
        case '(null)':
            return;
    }

    // If there are any pair of quotes around tbe value then we need to remove it
    if (preg_match('/\A([\'"])(.*)\1\z/', $value, $matches)) {
        return $matches[2];
    }

    return $value;
}

/**
 * Loads a DotEnv file.
 *
 * @param  string|null  $path
 * @param  bool  $optional
 * @return array
 */
function load_dotenv_file(string $path = null, bool $optional = true): array {
    $env = [];

    if (empty($path)) {
        $path = getcwd().DIRECTORY_SEPARATOR.'.env';
    }

    if (!file_exists($path)) {
        if ($optional) {
            return $env;
        }
        throw new \InvalidArgumentException(sprintf('%s does not exist', $path));
    }

    if (!is_readable($path)) {
        throw new \RuntimeException(sprintf('%s file is not readable', $path));
    }

    $lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

    foreach ($lines as $line) {
        if (strpos(trim($line), '#') === 0) {
            continue;
        }

        list($name, $value) = explode('=', $line, 2);
        $name = trim($name);
        $value = trim($value, " \n\r\t\v\x00\"");
        $value = parse_raw_value($value);
        $env[$name] = $value;
    }

    foreach ($env as $name => $value) {
        putenv(sprintf('%s=%s', $name, $value));
        $_ENV[$name] = $value;
        $_SERVER[$name] = $value;
    }

    return $env;
}