<?php

/*
 * This file is part of the AuthStack project.
 *
 * (c) Buckhill Ltd <development@buckhill.co.uk>
 *
 * This source file is subject to the Buckhill license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Buckhill\License\Model;

use Buckhill\License\Exceptions\InvalidSealedException;

class Seal
{
    protected $metadata;
    protected $payload;
    protected $signature;

    /**
     * Seal constructor.
     * @param $metadata
     * @param $payload
     * @param $signature
     */
    public function __construct($metadata, $payload, $signature)
    {
        $this->metadata = $metadata;
        $this->payload = $payload;
        $this->signature = $signature;
    }

    /**
     * @param $string
     * @return static
     * @throws InvalidSealedException
     */
    public static function fromString($string)
    {
        $pieces = explode('.', $string);

        if(count($pieces) !== 3)
        {
            throw new InvalidSealedException("Invalid seal provided, expected 3 pieces, got " . count($pieces));
        }

        return new static($pieces[0], $pieces[1], $pieces[2]);
    }

    /**
     * @param $key
     * @return bool
     */
    public function verifySignatureWith($key)
    {
        $signature  = $this->getSignature(true);
        $expected   = hash_hmac('sha256', sprintf("%s.%s", $this->getMetadata(), $this->getPayload()), $key, true);

        return 0 === strcmp($signature, $expected);
    }


    /**
     * @return string
     */
    public function toString()
    {
        return sprintf("%s.%s.%s", $this->getMetadata(), $this->getPayload(), $this->getSignature());
    }

    /**
     * @param bool $decode
     * @return string
     */
    public function getMetadata($decode = false)
    {
        if($decode)
        {
            return base64_decode($this->metadata);
        }

        return $this->metadata;
    }

    /**
     * @return string
     */
    public function getPayload()
    {
        return $this->payload;
    }

    /**
     * @param bool $decode
     * @return string
     */
    public function getSignature($decode = false)
    {
        if($decode)
        {
            return base64_decode($this->signature);
        }

        return $this->signature;
    }
}