<?php

/**
 * To run this script use this command: php index.php script/mqtt/subscribe
 * 
 *  * On Local Testing php index.php script/mqtt/subscribe "any additional parameter"
 *      Example:- php index.php script/mqtt/subscribe "auth" "8626-7113-004B-1600"

 *  In linux
 *  /opt/cpanel/ea-php74/root/usr/bin/php index.php script/mqtt/subscribe
 */

namespace App\Controllers\Scripts\MqttScripts;

require_once APPPATH . 'Libraries/MosquittoMqtt.php';

use App\Controllers\ScriptController;
use Libraries\MosquittoMqtt;

class SubscribeMqttController extends ScriptController {

    public $g_strReceivedTopic;

    public function index( $strArgument1 = NULL, $strArgument2 = NULL ) {
       
        echo 'Subscription process has been started' . PHP_EOL;
        
        if( true == isVal( $strArgument1 ) && true == isVal( $strArgument2 ) ) {
            $this->testingData( $strArgument1, $strArgument2 );

            echo 'Local testing process has been completed.' . PHP_EOL;
            exit;
        }

        $objMosquittoMqtt = new MosquittoMqtt();
       
        $objMosquittoMqtt->getConnection();
        
        $objMqttClient = $objMosquittoMqtt->getMqttClient();
       
        echo 'MQTT connection has been successfully done' . PHP_EOL;
        
        $objHandler = function( \PhpMqtt\Client\MqttClient $objMqttClient, string $strTopic, string $strPayload, int $qualityOfService, bool $retained ) use( $objMosquittoMqtt ) {
            
            $strMessage = 'Received message on topic ' . $strTopic . ' with Payload : ' . $strPayload;
            
            $this->g_objServiceLibrary->logger( $strMessage, 'mqtt-logs/subscribe/subscribe_message_' . replaceDateTimeDashFormatToUnderscore( CURRENT_DATE ) );

            $this->g_strReceivedTopic = $strTopic;
            
            $this->mqttServices( $strPayload );
        };

        $objMqttClient->registerMessageReceivedEventHandler( $objHandler );
    
        // Subscribe to all topics starting with 'diioT-1/soyorms/subscribe/' using QoS 0.
        $objMqttClient->subscribe( self::MQTT_TOPIC . 'sub/#' );
        
        // Start the event loop to receive messages on subscribed topics.
        $objMqttClient->loop(true);
        
        // Gracefully terminate the connection to the broker.
        $objMqttClient->disconnect();
        
        echo 'Topic has been successfully subscribed' . PHP_EOL;
        
    }

    private function mqttServices( $strMqttPayload ) {
       
        try {
            
            $this->validateMqttRequestData( $strMqttPayload );
            
            if( true == $this->g_boolIsMqttValidateRequest ) {

                $this->g_arrmixRequestRawData['received_topic'] = $this->g_strReceivedTopic;

                $strMethodName = $this->getRequestMethodName();

                switch( $strMethodName ) {
        
                    case 'actionOtp':
                        $objServiceHandler = new \App\Controllers\MqttServices\MqttServiceAuthenticationsController( $this->g_arrmixRequestRawData );
                        $arrmixResponseData = $objServiceHandler->$strMethodName();
                        break;
                    
                    case 'actionData':
                        $objReceivedDataPacketController = new \App\Controllers\MqttServices\DataPacketController( $this->g_arrmixRequestRawData );
                        $arrmixResponseData = $objReceivedDataPacketController->$strMethodName();
                        break;

                    case 'actionStatus':
                        $objUserController = new \App\Controllers\MqttServices\UsersController( $this->g_arrmixRequestRawData );
                        $arrmixResponseData = $objUserController->$strMethodName();
                        break;
                        
                    default:
                        $this->generateMqttError( 'error', ERROR_METHOD_NAME_NOT_FOUND, 'Method name ' . $this->getRequestMethodName() . ' not found', ERROR_TYPE_MESSAGE_METHOD_NAME_NOT_FOUND );
                }
                
                $this->generateMqttSuccess( $arrmixResponseData );
            }    

        } catch( \RuntimeException $objRuntimeException ) {
            
            return $objRuntimeException->getMessage();

        } catch( \Exception $objException ) {
            
            $strErrorDetails = 'Error :- ' . $objException->getMessage() . ' Code :- ' . $objException->getCode() . '. File :- ' .  $objException->getFile() . ' Line :- ' . $objException->getLine(); 

            $this->logger( $strErrorDetails, 'exceptions/' . replaceDateTimeDashFormatToUnderscore( CURRENT_DATE ) );
            
            return $objException->getMessage();
        }   
    }

    private function testingData( $strMsgId, $strGatewayMacAddress ) {

        switch( $strMsgId ) {

            case self::MSGID_AUTH:
                
                $strPayload = '{
                    "payload": "devices",
                    "method": "otp",
                    "auth": {
                        "token": "xyruNYqnUdVp/JeBoVwZjoOPia126j/aorDZo79rDa/M2uDAEwrVgr/hpBNUxE5IQO45D7WwjLEHJRGcvEkoIngq9Bw9+w9TLfDjRNdR1krHEMFq2W0kg8xdND8FZG+uglNzVnfoTC4qdE+ZDJsn+/5JqVMZdHpdBrlhBER4+y9WbSi9NC37ZO83jI/MHfvCA3MYRnCir/x43j2FJ3PKyx49zmrfE4drPAYgkFCu58PGk3buZizntZT/0SD3aeAy6Xg3JUZYVqEC7l03G3l4qFSOcpuONYJbLAigfy8VP9l7bCZykT6yOHwiztEMBkWTeT6Fvms0sl/559m8ObDXP+XjNVrdU20SGmQIvPbmyhdnxldkddCSk3i7Wk4TgSXLW2Wvis/dAzVq05aI"
                    },
                    "params": {
                        "g_mac": "' . $strGatewayMacAddress . '"
                    }
                }';

                break;
            
            case self::MSGID_TOPICS:

                $strPayload = '{
                    "payload": "devices",
                    "method": "mqtt_topics",
                    "auth": {
                        "type": "devices",
                        "otp": 915529
                    },
                    "params": {}
                }';
            
                break;
            
            case self::MSGID_DATA:

                $strPayload = '{
                    "payload": "devices",
                    "method": "data",
                    "auth": {
                        "type": "devices",
                        "otp": "915529"
                    },
                    "params": {
                        "p_id": 12,
                        "d_mac": "715B871B004B1203",
                        "model_no": "DT-EN-03B01-1A-2C-IN-C",
                        "epoach": 123456,
                        "fm_v": 12,
                        "d_type": 10,
                        "b_level": 100,
                        "d_temp": 100,
                        "fault": 100,
                        "alert": 1,
                        "value": {
                            "P1": 10,
                            "P2": 25,
                            "P3": 96,
                            "P4": 56,
                            "P5": 85,
                            "P6": 96,
                            "P7": 64,
                            "P8": 37,
                            "P9": 18,
                            "P10": 91,
                            "P11": 53,
                            "P12": 42,
                            "P13": 28,
                            "P14": 99,
                            "P15": 1, 
                            "P16": 2, 
                            "P17": 73.77597941920922,
                            "P18": 18.52061575854925 
                        }
                    }
                }';
                break;

            case self::MSGID_STATUS:
                
                $strPayload = '{
                    "payload": "devices",
                    "method": "status",
                    "auth": {
                        "otp": 617988
                    },
                    "params": {
                        "p_id": 11,
                        "epoach": 123456,
                        "msgid": "reqdata",
                        "msgstatus": "write",
                        "reqdata": {
                            "d_hb": 5,
                            "h_hb": 30,
                            "rst": 0,
                            "rtc_s": 0,
                            "pmp_s": 1,
                            "d_logs": 0
                        }
                    }
                }';    
                
                break;
            default:
                $strPayload = NULL;
        }


        if( false == isVal( $strPayload ) ) {
            echo "unable to send data to mqtt services". PHP_EOL;
            exit;
        }

        $this->g_strReceivedTopic = self::MQTT_TOPIC . 'sub/'. $strGatewayMacAddress . '/' . $strMsgId;

        echo $this->mqttServices( $strPayload ) . PHP_EOL;
        
        echo "Sent data successfully". PHP_EOL;
        exit;
    }


}
