<?php
/**
 * Cast Conductor Proprietary License v5
 * SPDX-License-Identifier: LicenseRef-CastConductor-Proprietary-v5
 * 
 * Copyright (c) 2025 CastConductor.com. All Rights Reserved.
 * 
 * This file is part of Cast Conductor ("Software"). The Software and its source
 * code constitute proprietary, confidential, and trade secret information of
 * CastConductor.com ("Company"). Any access or use is governed strictly by the
 * Cast Conductor Proprietary License v5 ("License"). By installing, copying,
 * accessing, compiling, or otherwise using the Software you agree to be bound by
 * all terms of the License. If you do not agree, you must cease use immediately.
 * 
 * Key Terms (Summary – see full License for binding terms):
 *  1. No Redistribution: You may not publish, distribute, sublicense, rent,
 *     lease, transfer, sell, or otherwise make the Software (or any derivative)
 *     available to any third party without prior written consent of Company.
 *  2. No Modification: Modification, reverse engineering, decompilation, or
 *     disassembly is prohibited except to the limited extent expressly permitted
 *     by applicable law that cannot be contractually waived.
 *  3. Confidentiality: Treat all source code and related artifacts as Company
 *     Confidential Information. Maintain at least the same degree of care as for
 *     your own confidential materials, and not less than reasonable care.
 *  4. No Patent License: No express or implied patent rights are granted. Future
 *     patents (if any) are fully reserved.
 *  5. No Trademark License: Company names, marks, and logos may not be used
 *     without prior written permission.
 *  6. Limited Internal Use: Use is limited solely to internal evaluation and
 *     operation of licensed Cast Conductor deployments. Commercial hosting or
 *     resale as a service requires a separate written agreement.
 *  7. Telemetry & License Validation: The Software may periodically transmit a
 *     hashed installation identifier, domain (or site ID), plugin/app version,
 *     and a truncated (non-reversible) fragment of the license key solely to
 *     validate activation status and enforce licensing. This minimal "phone home"
 *     check contains no personal or content data. If optional telemetry is later
 *     introduced it will be limited to aggregate operational metrics (no PII),
 *     fully documented, and optionally disableable per published instructions.
 *  8. Third-Party Components: The Software may include open source components
 *     covered by their own licenses. See THIRD-PARTY-NOTICES.md. Those licenses
 *     govern their respective components; this License governs all remaining code.
 *  9. Export Compliance: You are responsible for compliance with all applicable
 *     export control and sanctions laws.
 * 10. Warranty Disclaimer: THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF
 *     ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO MERCHANTABILITY,
 *     FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT.
 * 11. Limitation of Liability: IN NO EVENT WILL COMPANY OR AUTHORS BE LIABLE FOR
 *     ANY INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE
 *     DAMAGES, OR LOST PROFITS, EVEN IF ADVISED OF THE POSSIBILITY.
 * 12. Acceptance: Use of the Software constitutes acceptance of the License.
 * 13. Enforcement: Unauthorized reproduction or distribution may result in civil
 *     and criminal penalties and will be prosecuted to the maximum extent allowed
 *     by law.
 * 
 * Authoritative EULA: EULA-v5.1.md (repository root – private) and https://castconductor.com/eula
 * Precedence: If this summary conflicts with the EULA, the EULA governs.
 * Revision: Current EULA revision v5.1 (subject to update; check EULA for current enterprise thresholds).
 * 
 * Full License text available from: licensing@castconductor.com
 * Security reports: security@castconductor.com
 * Commercial inquiries: licensing@castconductor.com
 * 
 * END OF HEADER
 */

/**
 * CastConductor REST API Core
 * 
 * Handles REST API registration and routing for all V5 endpoints
 * Implements standardized JSON response format
 */

if (!defined('ABSPATH')) {
    exit;
}

class CastConductor_REST_API {
    
    /**
     * API namespace
     */
    const API_NAMESPACE = 'castconductor/v5';
    
    /**
     * API major version number (for cross-app handshake)
     */
    const API_MAJOR = 5;

    /**
     * API version
     */
    const API_VERSION = '5.0.0';
    
    /**
     * Content controller instance
     */
    private $content_controller;
    
    /**
     * Constructor
     */
    public function __construct() {
        // Initialize content controller
        $this->content_controller = new CastConductor_Content_Controller();
    }
    
    /**
     * Register all REST API routes
     */
    public function register_routes() {
        // Core Roku endpoints
        $this->register_roku_routes();
        
        // Management endpoints
        $this->register_management_routes();
        
        // Content endpoints
        $this->register_content_routes();
        
        // Enhanced feature endpoints
        $this->register_enhanced_routes();
    }
    
    /**
     * Register Roku integration endpoints
     */
    private function register_roku_routes() {
        // Master app configuration endpoint
        register_rest_route(self::API_NAMESPACE, '/roku/app-config', array(
            'methods' => 'GET',
            'callback' => array('CastConductor_Roku_Controller', 'get_app_config'),
            'permission_callback' => '__return_true', // Public endpoint
            'args' => array(
                'roku_id' => array(
                    'description' => 'Roku device identifier for personalization',
                    'type' => 'string',
                    'sanitize_callback' => 'sanitize_text_field',
                ),
                'ip_address' => array(
                    'description' => 'Roku IP address for geolocation',
                    'type' => 'string',
                    'sanitize_callback' => 'sanitize_text_field',
                ),
            ),
        ));
        
        // Stream configuration endpoint
        register_rest_route(self::API_NAMESPACE, '/roku/stream-config', array(
            'methods' => 'GET',
            'callback' => array('CastConductor_Roku_Controller', 'get_stream_config'),
            'permission_callback' => '__return_true', // Public endpoint
        ));
        
        // Single content block for Roku overlay (public endpoint for menu-driven content)
        register_rest_route(self::API_NAMESPACE, '/roku/content-block/(?P<id>[\d]+)', array(
            'methods' => 'GET',
            'callback' => array('CastConductor_Roku_Controller', 'get_content_block_for_roku'),
            'permission_callback' => '__return_true', // Public endpoint - Roku device access
            'args' => array(
                'id' => array(
                    'description' => 'Content block ID',
                    'type' => 'integer',
                    'required' => true,
                    'sanitize_callback' => 'absint',
                ),
            ),
        ));
    }
    
    /**
     * Register management endpoints
     */
    private function register_management_routes() {
        // Content Blocks CRUD - Updated to use new controller
        $content_blocks_controller = new CastConductor_Content_Blocks_Controller();
        $content_blocks_controller->register_routes();

        // Scenes management - new controller
        if (class_exists('CastConductor_Scenes_Controller')) {
            $scenes_controller = new CastConductor_Scenes_Controller();
            $scenes_controller->register_routes();
        }

        // Menu Builder controller - Hierarchical navigation menus
        if (class_exists('CastConductor_Menu_Controller')) {
            $menu_controller = new CastConductor_Menu_Controller();
            $menu_controller->register_routes();
        }
    }
    
    /**
     * Register content endpoints
     */
    private function register_content_routes() {
        // Register content controller routes
        $this->content_controller->register_routes();
    }
    
    /**
     * Register enhanced feature endpoints
     */
    private function register_enhanced_routes() {
        // Enhanced album artwork discovery - Register the full controller
        $artwork_controller = new CastConductor_Artwork_Controller();
        $artwork_controller->register_routes();
        
        // Album artwork discovery controller
        $album_artwork_controller = new CastConductor_Album_Artwork_Controller();
        $album_artwork_controller->register_routes();
        
        // Metadata proxy controller - Enhanced artwork + manual overrides
        $metadata_proxy_controller = new CastConductor_Metadata_Proxy_Controller();
        $metadata_proxy_controller->register_routes();
        
        // Canvas Editor controller
        $canvas_editor_controller = new CastConductor_Canvas_Editor_Controller();
        $canvas_editor_controller->register_routes();
        
        // Containers controller - Phase 3 Implementation
        $containers_controller = new CastConductor_Containers_Controller();
        $containers_controller->register_routes();
        
        // Background Layer controller - Phase 3 Priority 1
        $background_controller = new CastConductor_Background_Controller();
        $background_controller->register_routes();
        
        // Shoutout Moderation controller
        $shoutout_moderation_controller = new CastConductor_Shoutout_Moderation_Controller();
        $shoutout_moderation_controller->register_routes();
        
        // Feed Parser controller - Phase 4 Video Support
        $feed_controller = new CastConductor_Feed_Controller();
        $feed_controller->register_routes();
        
        // Deep Link controller - Phase 6 Deep Linking
        $deep_link_controller = new CastConductor_Deep_Link_Controller();
        $deep_link_controller->register_routes();
        
        // Global settings
        register_rest_route(self::API_NAMESPACE, '/settings', array(
            array(
                'methods' => 'GET',
                'callback' => array('CastConductor_Settings_Controller', 'get_settings'),
                'permission_callback' => array($this, 'check_admin_permissions'),
            ),
            array(
                'methods' => 'POST',
                'callback' => array('CastConductor_Settings_Controller', 'update_settings'),
                'permission_callback' => array($this, 'check_admin_permissions'),
                'args' => $this->get_settings_schema(),
            ),
        ));
    }
    
    /**
     * Check admin permissions
     */
    public function check_admin_permissions() {
        return current_user_can('manage_options');
    }
    
    /**
     * Standardized API response format
     */
    public static function format_response($data, $success = true, $message = '', $total = null) {
        $response = array(
            'success' => $success,
            'data' => $data,
            'timestamp' => current_time('c'), // ISO 8601 format
            'version' => self::API_VERSION
        );
        
        if (!empty($message)) {
            $response['message'] = $message;
        }
        
        if ($total !== null) {
            $response['total'] = $total;
        }
        
        return rest_ensure_response($response);
    }
    
    /**
     * Standardized error response
     */
    public static function error_response($message, $code = 'error', $status = 400, $data = null) {
        $response = array(
            'success' => false,
            'error' => array(
                'code' => $code,
                'message' => $message
            ),
            'timestamp' => current_time('c'),
            'version' => self::API_VERSION
        );
        
        if ($data !== null) {
            $response['data'] = $data;
        }
        
        return new WP_Error($code, $message, array('status' => $status, 'response' => $response));
    }
    
    /**
     * Get container schema for validation
     */
    private function get_container_schema() {
        return array(
            'name' => array(
                'required' => true,
                'type' => 'string',
                'sanitize_callback' => 'sanitize_text_field',
            ),
            'type' => array(
                'required' => true,
                'type' => 'string',
                'enum' => array('lower_third_container', 'sidebar_container', 'fullscreen_container', 'corner_container', 'banner_container'),
            ),
            'enabled' => array(
                'type' => 'boolean',
                'default' => true,
            ),
        );
    }
    
    /**
     * Get content block schema for validation
     */
    private function get_content_block_schema() {
        return array(
            'name' => array(
                'required' => true,
                'type' => 'string',
                'sanitize_callback' => 'sanitize_text_field',
            ),
            'type' => array(
                'required' => true,
                'type' => 'string',
                'enum' => array('track_info', 'weather', 'location_time', 'shoutout', 'sponsor', 'promo', 'custom_api', 'custom'),
            ),
            'visual_config' => array(
                'required' => true,
                'type' => 'object',
            ),
            'data_config' => array(
                'type' => 'object',
            ),
            'enabled' => array(
                'type' => 'boolean',
                'default' => true,
            ),
        );
    }
    
    /**
     * Get assignment schema for validation
     */
    private function get_assignment_schema() {
        return array(
            'container_id' => array(
                'required' => true,
                'type' => 'integer',
                'sanitize_callback' => 'absint',
            ),
            'content_block_id' => array(
                'required' => true,
                'type' => 'integer',
                'sanitize_callback' => 'absint',
            ),
            'rotation_order' => array(
                'type' => 'integer',
                'default' => 1,
                'sanitize_callback' => 'absint',
            ),
            'rotation_percentage' => array(
                'type' => 'number',
                'default' => 10.0,
                'minimum' => 0.1,
                'maximum' => 100.0,
            ),
            'enabled' => array(
                'type' => 'boolean',
                'default' => true,
            ),
        );
    }
    
    /**
     * Get settings schema for validation
     */
    private function get_settings_schema() {
        return array(
            'stream_url' => array(
                'type' => 'string',
                'format' => 'uri',
                'sanitize_callback' => 'esc_url_raw',
            ),
            'metadata_url' => array(
                'type' => 'string',
                'format' => 'uri',
                'sanitize_callback' => 'esc_url_raw',
            ),
            'openweather_api_key' => array(
                'type' => 'string',
                'sanitize_callback' => 'sanitize_text_field',
            ),
            'artwork_search_enabled' => array(
                'type' => 'boolean',
            ),
            'geolocation_enabled' => array(
                'type' => 'boolean',
            ),
        );
    }
}
