<?php
/**
 * app/classes/api_controller.php
 *
 * This is the base api controller. Every other api controller should
 * extend this class.
 *
 * @version 3.0
 * @author  Joey Kimsey <Joey@thetempusproject.com>
 * @link    https://TheTempusProject.com
 * @license https://opensource.org/licenses/MIT [MIT LICENSE]
 */
namespace TheTempusProject\Classes;

use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\Bedrock\Functions\Session;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Models\Token;
use TheTempusProject\Canary\Bin\Canary as Debug;
use TheTempusProject\Houdini\Classes\Views;

class ApiController extends Controller {
    protected static $canAccessApplicationApi = false;
    protected static $canAccessUserApi = false;
    protected static $canAccessAuthenticationApi = false;
    protected static $authToken;

    public function __construct( $secure = true ) {
        header('Content-Type: application/json; charset=utf-8');
        parent::__construct();
        Template::setTemplate( 'api' );
        Template::noFollow();
        Template::noIndex();
        $res = $this->verifyApiRequest();
        if ( $secure && ! $this->canUseApi() ) {
            exit( $res );
        }
    }

    protected function canUseApi() {
        return ( $this->canUseUserApi() || $this->canUseAppApi() || $this->canUseAuthApi() );
    }

    protected function canUseUserApi() {
        $apiEnabled = Config::getValue( 'api/apiAccessApp' );
        if ( empty( $apiEnabled ) ) {
            return false;
        }
        return self::$canAccessUserApi;
    }

    protected function canUseAppApi() {
        $apiEnabled = Config::getValue( 'api/apiAccessPersonal' );
        if ( empty( $apiEnabled ) ) {
            return false;
        }
        return self::$canAccessApplicationApi;
    }

    protected function canUseAuthApi() {
        return self::$canAccessAuthenticationApi;
    }

    public function verifyApiRequest() {
        $tokens = new Token;
        $secret = null;

        $bearer_token = $this->getBearerToken();
        if ( ! empty( $bearer_token ) ) {
            $token = $tokens->findByToken( $bearer_token );
        } else {
            $secret = $this->getSecretToken();
            if ( empty( $secret ) ) {
                return Views::simpleView( 'api.response', ['response' => json_encode( [ 'error' => 'invalid secret' ], true )]);
            }
            $token = $tokens->findBySecret( $secret );
        }
        if ( empty( $token ) ) {
            return Views::simpleView( 'api.response', ['response' => json_encode( [ 'error' => 'invalid token' ], true )]);
        }
        self::$authToken = $token;
        if ( $token->expiresAt <= time() && empty( $secret ) ) {
            return Views::simpleView( 'api.response', ['response' => json_encode( [ 'error' => 'token expired' ], true )]);
        }
        if ( $token->expiresAt <= time() ) {
            self::$canAccessAuthenticationApi = true;
            return;
        }
        if ( $token->token_type == 'app' ) {
            self::$canAccessApplicationApi = true;
            return;
        }
        if ( $token->token_type == 'user' ) {
            self::$canAccessUserApi = true;
            return;
        }
        return $result;
    }

    public function getSecretToken() {
        $headers = $this->getAuthorizationHeader();
        if ( ! empty( $headers ) ) {
            if ( preg_match( '/Secret\s(\S+)/', $headers, $matches ) ) {
                return $matches[1];
            }
        }
        return null;
    }

    public function getBearerToken() {
        $headers = $this->getAuthorizationHeader();
        if ( ! empty( $headers ) ) {
            if ( preg_match( '/Bearer\s(\S+)/', $headers, $matches ) ) {
                return $matches[1];
            }
        }
        return null;
    }

    public function getAuthorizationHeader(){
        $headers = null;
        if ( isset( $_SERVER['Authorization'] ) ) {
            $headers = trim( $_SERVER["Authorization"] );
        } elseif ( isset( $_SERVER['HTTP_AUTHORIZATION'] ) ) {
            $headers = trim( $_SERVER["HTTP_AUTHORIZATION"] );
        } elseif ( function_exists( 'apache_request_headers' ) ) {
            $requestHeaders = apache_request_headers();
            $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
            if ( isset( $requestHeaders['Authorization'] ) ) {
                $headers = trim( $requestHeaders['Authorization'] );
            }
        }
        return $headers;
    }
}
