<?php

namespace Buckhill\Yubico\Modes\Yubikey;

class Yubikey
{
    protected $attributes = [];

    public function __construct($public_id, $private_id, $secret_key, $use_counter = 0, $session_counter = 0)
    {
        $this
            ->setPublicId($public_id)
            ->setPrivateId($private_id)
            ->setSecretKey($secret_key)
            ->setUseCounter($use_counter)
            ->setSessionCounter($session_counter);
    }


    /**
     * @param array $data
     *
     * @return static
     */
    public static function fromArray(array $data)
    {
        static::validate($data);

        return new static($data['public_id'], $data['private_id'], $data['secret_key'], $data['use_counter'], $data['session_counter']);
    }


    /**
     * @param array $data
     *
     * @return bool
     */
    protected static function validate(array $data)
    {
        $required = ['public_id', 'private_id', 'secret_key', 'use_counter', 'session_counter'];

        foreach($required as $key)
        {
            if(!isset($data[$key]))
            {
                throw new \InvalidArgumentException(sprintf("Required key %s was not specified in the input array.", $key));
            }
        }

        return true;
    }

    /**
     * @param $public_id
     *
     * @return Yubikey
     */
    public function setPublicId($public_id)
    {
        return $this->set('public_id', $public_id);
    }


    /**
     * @return mixed|null
     */
    public function getPublicId()
    {
        return $this->get('public_id');
    }


    /**
     * @param $private_id
     *
     * @return Yubikey
     */
    public function setPrivateId($private_id)
    {
        return $this->set('private_id', $private_id);
    }


    /**
     * @return mixed|null
     */
    public function getPrivateId()
    {
        return $this->get('private_id');
    }

    /**
     * @param $secret_key
     *
     * @return Yubikey
     */
    public function setSecretKey($secret_key)
    {
        return $this->set('secret_key', $secret_key);
    }


    /**
     * @param bool|true $binary
     *
     * @return mixed|string
     */
    public function getSecretKey($binary = true)
    {
        $key = str_replace(' ', '', $this->get('secret_key'));

        if($binary)
        {
            return hex2bin($key);
        }

        return $key;
    }

    /**
     * @param int $counter
     *
     * @return Yubikey
     */
    public function setUseCounter($counter = 0)
    {
        return $this->set('use_counter', $counter);
    }


    /**
     * @return mixed|null
     */
    public function getUseCounter()
    {
        return $this->get('use_counter');
    }


    /**
     * @param int $counter
     *
     * @return Yubikey
     */
    public function setSessionCounter($counter = 0)
    {
        return $this->set('session_counter', $counter);
    }


    /**
     * @return mixed|null
     */
    public function getSessionCounter()
    {
        return $this->get('session_counter');
    }

    /**
     * @param $key
     * @param $value
     *
     * @return $this
     */
    protected function set($key, $value)
    {
        $this->attributes[$key] = $value;

        return $this;
    }


    /**
     * @param      $key
     * @param null $default
     *
     * @return mixed|null
     */
    protected function get($key, $default = null)
    {
        return isset($this->attributes[$key]) ? $this->attributes[$key] : $default;
    }


    /**
     * @param string $string
     *
     * @return mixed
     */
    protected function rmspace($string = '')
    {
        return str_replace(' ', '', $string);
    }
}