<?php

namespace Buckhill\License\Model;

use Buckhill\Support\Traits\DotNotationAccessorTrait;
use Buckhill\License\Exceptions\InvalidPeriodException;
use Buckhill\License\Exceptions\InvalidTimestampException;

class DecryptedLicense
{
    use DotNotationAccessorTrait;

    protected $model;

    public function __construct(array $model)
    {
        $this->model = $model;
    }

    /**
     * @return bool
     */
    public function isExpired()
    {
        $expiry = $this->getEndsAt();

        $now = $this->now();

        return $expiry->getTimestamp() < $now->getTimestamp();
    }

    /**
     * @param string $period
     * @return bool
     */
    public function isInGracePeriod($period = '7 days')
    {
        $grace = $this->getGraceFrom($this->dotNotationFromModel('license.gracePeriod', $period));

        $now = $this->now();

        // If today is less than grace period..
        return $now->getTimestamp() < $grace->getTimestamp();
    }

    /**
     * @param string $domain
     * @return bool
     */
    public function domainIs($domain = '')
    {
        return in_array($domain, $this->dotNotationFromModel('domain', []));
    }

    /**
     * @return \DateTime
     */
    public function getStartsAt()
    {
        return $this->getDateTimeFromTS($this->dotNotationFromModel('license.startsAt', 0));
    }

    /**
     * @return \DateTime
     */
    public function getEndsAt()
    {
        return $this->getDateTimeFromTS($this->dotNotationFromModel('license.endsAt', 0));
    }

    /**
     * @param int $ts
     * @return \DateTime
     * @throws InvalidTimestampException
     */
    protected function getDateTimeFromTS($ts = 0)
    {
        $dt = new \DateTime("now", new \DateTimeZone("UTC"));

        $result = $dt->setTimestamp($ts);

        if(!$result instanceof \DateTime)
        {
            throw new InvalidTimestampException(sprintf("Invalid timestamp: %s", $ts));
        }

        return $result;
    }

    /**
     * @param string $period
     *
     * @return \DateTime
     * @throws InvalidPeriodException
     */
    protected function getGraceFrom($period = '')
    {
        $dt = $this->getEndsAt();

        if(false === $dt->modify($period))
        {
            throw new InvalidPeriodException(sprintf("Invalid period: %s", $period));
        }

        return $dt;
    }

    /**
     * @return \DateTime
     */
    protected function now()
    {
        return new \DateTime("now", new \DateTimeZone("UTC"));
    }
}