<?php

namespace AuthStack\AuthProfile\Model;

use AuthStack\Driver\Model\User;
use Illuminate\Database\Eloquent\ModelNotFoundException;

class AuthProfile
{
    protected $protocol;
    protected $data = [];


    /**
     * @param array $data
     *
     * @return static
     */
    public static function fromArray(array $data)
    {
        $me = new static;

        $me->protocol = isset($data['protocol']) ? $data['protocol'] : 'N/A';
        $me->data = $data;

        return $me;
    }


    /**
     * @return int
     */
    public function getConnectionId()
    {
        return $this->fromData('conn_id');
    }


    /**
     * @return int
     */
    public function getApplicationId()
    {
        return $this->fromData('application_id');
    }


    /**
     * @return string
     */
    public function getSessionId()
    {
        return $this->fromData('session_id');
    }


    /**
     * @return int
     */
    public function getUserId()
    {
        return $this->fromData('user_id');
    }


    /**
     * @return User
     * @throws ModelNotFoundException
     */
    public function getProvisionedUser()
    {
        return User::findOrFail($this->getUserId());
    }


    /**
     * Returns an array of data that gets saved to the session. This is required for retrieving authentication info later on
     *
     * @return array
     */
    public function serializeForSession()
    {
        return [

            // Protocol used (SAML, OAuth, OpenID)
            'protocol'          => $this->fromData('protocol'),

            // Session identifier assigned by the protocol handler
            'session_id'        => $this->fromData('session_id'),

            // Connection id (authentication source, look at drivers_connections table)
            'conn_id'           => $this->fromData('conn_id'),

            // Application that initiated SSO (service provider)
            'application_id'    => $this->fromData('application_id'),

            // Primary key from users table - this is internal to authstack
            'user_id'           => $this->fromData('user_id'),

            // Browser used during authentication - used for informational purposes. Can be used to verify is session was hijacked (not implemented)
            'browser'           => $this->fromData('browser'),

            // IP during authentication. Used for informational purposes. Can be used to verify the origin at a later point (not implemented).
            'ip'                => $this->fromData('ip'),

            // Created at in format of Y-m-d H:i:s in UTC (timestamp MySQL format)
            'created_at'        => $this->fromData('created_at')
        ];
    }


    /**
     * @param callable|null $callback
     *
     * @return array
     */
    public function toArray(callable $callback = null)
    {
        $data = $this->serializeForSession();

        $extra = is_callable($callback) ? $callback() : [];

        return array_merge($data, is_array($extra) ? $extra : []);
    }


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