<?php

/**
 * This file is part of the Carbon package.
 *
 * (c) Brian Nesbitt <brian@nesbot.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Carbon\Traits;

use Carbon\CarbonInterface;
use Carbon\CarbonTimeZone;
use Closure;
use DateTimeImmutable;
use DateTimeInterface;
use InvalidArgumentException;
use Throwable;

trait Test
{
    ///////////////////////////////////////////////////////////////////
    ///////////////////////// TESTING AIDS ////////////////////////////
    ///////////////////////////////////////////////////////////////////

    /**
     * A test Carbon instance to be returned when now instances are created.
     *
     * @var static
     */
    protected static $testNow;

    /**
     * The timezone to resto to when clearing the time mock.
     *
     * @var string|null
     */
    protected static $testDefaultTimezone;

    /**
     * Set a Carbon instance (real or mock) to be returned when a "now"
     * instance is created.  The provided instance will be returned
     * specifically under the following conditions:
     *   - A call to the static now() method, ex. Carbon::now()
     *   - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null)
     *   - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now')
     *   - When a string containing the desired time is passed to Carbon::parse().
     *
     * Note the timezone parameter was left out of the examples above and
     * has no affect as the mock value will be returned regardless of its value.
     *
     * Only the moment is mocked with setTestNow(), the timezone will still be the one passed
     * as parameter of date_default_timezone_get() as a fallback (see setTestNowAndTimezone()).
     *
     * To clear the test instance call this method using the default
     * parameter of null.
     *
     * /!\ Use this method for unit tests only.
     *
     * @param Closure|static|string|false|null $testNow real or mock Carbon instance
     */
    public static function setTestNow($testNow = null)
    {
        if ($testNow === false) {
            $testNow = null;
        }

        static::$testNow = \is_string($testNow) ? static::parse($testNow) : $testNow;
    }

    /**
     * Set a Carbon instance (real or mock) to be returned when a "now"
     * instance is created.  The provided instance will be returned
     * specifically under the following conditions:
     *   - A call to the static now() method, ex. Carbon::now()
     *   - When a null (or blank string) is passed to the constructor or parse(), ex. new Carbon(null)
     *   - When the string "now" is passed to the constructor or parse(), ex. new Carbon('now')
     *   - When a string containing the desired time is passed to Carbon::parse().
     *
     * It will also align default timezone (e.g. call date_default_timezone_set()) with
     * the second argument or if null, with the timezone of the given date object.
     *
     * To clear the test instance call this method using the default
     * parameter of null.
     *
     * /!\ Use this method for unit tests only.
     *
     * @param Closure|static|string|false|null $testNow real or mock Carbon instance
     */
    public static function setTestNowAndTimezone($testNow = null, $tz = null)
    {
        if ($testNow) {
            self::$testDefaultTimezone = self::$testDefaultTimezone ?? date_default_timezone_get();
        }

        $useDateInstanceTimezone = $testNow instanceof DateTimeInterface;

        if ($useDateInstanceTimezone) {
            self::setDefaultTimezone($testNow->getTimezone()->getName(), $testNow);
        }

        static::setTestNow($testNow);

        if (!$useDateInstanceTimezone) {
            $now = static::getMockedTestNow(\func_num_args() === 1 ? null : $tz);
            $tzName = $now ? $now->tzName : null;
            self::setDefaultTimezone($tzName ?? self::$testDefaultTimezone ?? 'UTC', $now);
        }

        if (!$testNow) {
            self::$testDefaultTimezone = null;
        }
    }

    /**
     * Temporarily sets a static date to be used within the callback.
     * Using setTestNow to set the date, executing the callback, then
     * clearing the test instance.
     *
     * /!\ Use this method for unit tests only.
     *
     * @param Closure|static|string|false|null $testNow  real or mock Carbon instance
     * @param Closure|null                     $callback
     *
     * @return mixed
     */
    public static function withTestNow($testNow = null, $callback = null)
    {
        static::setTestNow($testNow);
        $result = $callback();
        static::setTestNow();

        return $result;
    }

    /**
     * Get the Carbon instance (real or mock) to be returned when a "now"
     * instance is created.
     *
     * @return Closure|static the current instance used for testing
     */
    public static function getTestNow()
    {
        return static::$testNow;
    }

    /**
     * Determine if there is a valid test instance set. A valid test instance
     * is anything that is not null.
     *
     * @return bool true if there is a test instance, otherwise false
     */
    public static function hasTestNow()
    {
        return static::getTestNow() !== null;
    }

    /**
     * Get the mocked date passed in setTestNow() and if it's a Closure, execute it.
     *
     * @param string|\DateTimeZone $tz
     *
     * @return \Carbon\CarbonImmutable|\Carbon\Carbon|null
     */
    protected static function getMockedTestNow($tz)
    {
        $testNow = static::getTestNow();

        if ($testNow instanceof Closure) {
            $realNow = new DateTimeImmutable('now');
            $testNow = $testNow(static::parse(
                $realNow->format('Y-m-d H:i:s.u'),
                $tz ?: $realNow->getTimezone()
            ));
        }
        /* @var \Carbon\CarbonImmutable|\Carbon\Carbon|null $testNow */

        return $testNow instanceof CarbonInterface
            ? $testNow->avoidMutation()->tz($tz)
            : $testNow;
    }

    protected static function mockConstructorParameters(&$time, $tz)
    {
        /** @var \Carbon\CarbonImmutable|\Carbon\Carbon $testInstance */
        $testInstance = clone static::getMockedTestNow($tz);

        if (static::hasRelativeKeywords($time)) {
            $testInstance = $testInstance->modify($time);
        }

        $time = $testInstance instanceof self
            ? $testInstance->rawFormat(static::MOCK_DATETIME_FORMAT)
            : $testInstance->format(static::MOCK_DATETIME_FORMAT);
    }

    private static function setDefaultTimezone($timezone, DateTimeInterface $date = null)
    {
        $previous = null;
        $success = false;

        try {
            $success = date_default_timezone_set($timezone);
        } catch (Throwable $exception) {
            $previous = $exception;
        }

        if (!$success) {
            $suggestion = @CarbonTimeZone::create($timezone)->toRegionName($date);

            throw new InvalidArgumentException(
                "Timezone ID '$timezone' is invalid".
                ($suggestion && $suggestion !== $timezone ? ", did you mean '$suggestion'?" : '.')."\n".
                "It must be one of the IDs from DateTimeZone::listIdentifiers(),\n".
                'For the record, hours/minutes offset are relevant only for a particular moment, '.
                'but not as a default timezone.',
                0,
                $previous
            );
        }
    }
}
