<?php
namespace App\Controllers\Backend;

use App\Controllers\BackendController;
use App\Models\NetworkSettingsModel;
use App\Models\ComSettingsModel;
use App\Models\SlaveDevicesModel;

class DeviceComSettingsController extends BackendController {
    
    public function actionViewComSettings() {

        $arrmixResponseConfigData = $this->getConfigData();

        $arrmixDeviceConfigJsonFileData = $arrmixResponseConfigData['device_config_josn_file_data'];
        $intUsedConfigFile              = $arrmixResponseConfigData['used_config_file'];

        $arrmixBreadCrumbData['strContentHeader']     = 'COM Port';
        $arrmixBreadCrumbData['arrmixBreadCrumbList'] = [
            ['name' => 'COM Port', 'is_active' => true]
        ];
        
        $arrmixData                 = [];
        $arrmixData['strTitle']     = 'COM Port';
        $arrmixData['strCardTitle'] = 'View COM Port';
        if( DEVICE_MODE_CONVERTER == $arrmixDeviceConfigJsonFileData['dev_mode'] ) {
            
            $arrmixComSettingsDetails = [
                'mode'           => $arrmixDeviceConfigJsonFileData['rs485']['rs485_conf'],
                'baud_rate'      => $arrmixDeviceConfigJsonFileData['rs485']['br'],
                'data_bits'      => $arrmixDeviceConfigJsonFileData['rs485']['data_bit'],
                'parity_bits'    => $arrmixDeviceConfigJsonFileData['rs485']['par_bit'],
                'flow_control'   => $arrmixDeviceConfigJsonFileData['rs485']['fl_cntr'],
                'stop_bits'      => $arrmixDeviceConfigJsonFileData['rs485']['stop_bit']
            ];

            $arrmixData['arrmixComSettingsDetails']     = $arrmixComSettingsDetails;

            $arrmixData['view'] = 'device-com-settings/converter-com-view-details';
        } else {
            
            $arrmixData['arrmixSlaveDevicesList'] = ( true == isset( $arrmixDeviceConfigJsonFileData['slv_devices'] ) && true == isValArr( $arrmixDeviceConfigJsonFileData['slv_devices'] ) ) ? $arrmixDeviceConfigJsonFileData['slv_devices'] : [];

            $arrmixData['view'] = 'device-com-settings/gateway-list-slave-devices';
        }
        
        $arrmixData['arrmixBreadCrumbData'] = $arrmixBreadCrumbData;
        $arrmixData['intUsedConfigFile']    = $intUsedConfigFile;
        
        return $this->render( $arrmixData );
    }

    
    public function actionAddSlaveDevice() {
        
        $arrmixResponseConfigData = $this->getConfigData();

        $arrmixDeviceConfigJsonFileData = $arrmixResponseConfigData['device_config_josn_file_data'];
        $intUsedConfigFile              = $arrmixResponseConfigData['used_config_file'];

        $arrintSlaveIds = [];
        if( true == isset( $arrmixDeviceConfigJsonFileData['slv_devices'] ) && true == isValArr( $arrmixDeviceConfigJsonFileData['slv_devices'] ) ) {
            $arrmixSlaveDevicesList = $arrmixDeviceConfigJsonFileData['slv_devices'];

            $arrintSlaveIds = array_keys( \rekeyArray( $arrmixSlaveDevicesList, 'slv_id' ) );
        } 

        $arrmixBreadCrumbData['strContentHeader']     = 'Slave Devices';
        $arrmixBreadCrumbData['arrmixBreadCrumbList'] = [
            ['name' => 'Slave Devices', 'is_active' => false, 'href' => getBaseUrl() . 'device-settings/com-settings/view' ],
            ['name' => 'Add Slave Device', 'is_active' => true]
        ];

        $arrmixData                         = [];
        $arrmixData['strTitle']             = 'Add Slave Device';
        $arrmixData['strCardTitle']         = 'Add Slave Device';
        $arrmixData['view']                 = 'device-com-settings/gateway-slave-device-form-details';
        $arrmixData['arrmixBreadCrumbData'] = $arrmixBreadCrumbData;
        $arrmixData['arrintSlaveIds']       = $arrintSlaveIds;

        
        if( $this->request->getPost() ) {
            
            $arrmixRequestData = $this->request->getPost();
            
            if( false == $this->validation->run( $arrmixRequestData , 'validateSlaveDevice' ) ) { 
                
                $this->session->setFlashdata( 'error', 'Validation Errors. Please check the below errors.' );
                self::setFormValidationErrors( $this->validation->getErrors() );
                
                return $this->render( $arrmixData );
            }

            $arrmixSlaveDeviceDetails = $arrmixRequestData;

            array_map( 'intval', $arrmixSlaveDeviceDetails );
            
            $arrmixSlaveDeviceDetails['data_type'] = $arrmixRequestData['data_type'];

            $arrmixDeviceConfigJsonFileData['slv_devices'][] = $arrmixSlaveDeviceDetails;
            
            $this->g_objServiceLibrary->updateConfigFile( json_encode( $arrmixDeviceConfigJsonFileData ) );
            
            $this->session->setFlashdata( 'success', 'The new slave device has been added successfully.' );

            return redirect()->route( 'device-settings/com-settings/view' );
        }
        
        return $this->render( $arrmixData );
    }

    public function actionEditSlaveDevice() {

        $arrmixRequestData = $this->request->getGet();
        
        if( false == isset( $arrmixRequestData['slv_id'] ) || false == isValId( $arrmixRequestData['slv_id'] ) ) {
            
            $this->session->setFlashdata( 'error', 'Invalid Slave Id.' );
            
            return redirect()->route( 'device-settings/com-settings/view' );
        }

        $arrmixResponseConfigData = $this->getConfigData();

        $arrmixDeviceConfigJsonFileData = $arrmixResponseConfigData['device_config_josn_file_data'];
        $intUsedConfigFile              = $arrmixResponseConfigData['used_config_file'];

        if( false == isset( $arrmixDeviceConfigJsonFileData['slv_devices'] ) || false == isValArr( $arrmixDeviceConfigJsonFileData['slv_devices'] ) ) { 
            
            $this->session->setFlashdata( 'error', 'Unable to get slave devices list in config.' );
            
            return redirect()->route( 'device-settings/com-settings/view' );
        }   

        $arrmixSlaveDevicesList = \rekeyArray( $arrmixDeviceConfigJsonFileData['slv_devices'], 'slv_id' );
        
        if( false == isset( $arrmixSlaveDevicesList[$arrmixRequestData['slv_id']] ) ) {

            $this->session->setFlashdata( 'error', 'Unable to get data of provided slave id - ' . $arrmixRequestData['slv_id'] );
            
            return redirect()->route( 'device-settings/com-settings/view' );
        }

        $arrintSlaveIds = array_keys( $arrmixSlaveDevicesList );

        $arrmixSlaveDeviceDetails = $arrmixSlaveDevicesList[$arrmixRequestData['slv_id']];

        $arrmixBreadCrumbData['strContentHeader']     = 'Edit Slave Devices';
        $arrmixBreadCrumbData['arrmixBreadCrumbList'] = [
            ['name' => 'Slave Devices', 'is_active' => false, 'href' => getBaseUrl() . 'device-settings/com-settings/view' ],
            ['name' => 'Slave Id ' . $arrmixSlaveDeviceDetails['slv_id'], 'is_active' => true]
        ];

        $arrmixData                             = [];
        $arrmixData['strTitle']                 = 'Edit - Slave Id ' . $arrmixSlaveDeviceDetails['slv_id'];
        $arrmixData['strCardTitle']             = 'Edit - Slave Id ' . $arrmixSlaveDeviceDetails['slv_id'];
        $arrmixData['view']                     = 'device-com-settings/gateway-slave-device-form-details';
        $arrmixData['arrmixBreadCrumbData']     = $arrmixBreadCrumbData;
        $arrmixData['arrmixSlaveDeviceDetails'] = $arrmixSlaveDeviceDetails;
        $arrmixData['arrintSlaveIds']           = $arrintSlaveIds;
        
        if( $this->request->getPost() ) {
            
            $arrmixRequestData = $this->request->getPost();
            
            if( false == $this->validation->run( $arrmixRequestData , 'validateSlaveDevice' ) ) { 
                
                $this->session->setFlashdata( 'error', 'Validation Errors. Please check the below errors.' );
                self::setFormValidationErrors( $this->validation->getErrors() );
                
                return $this->render( $arrmixData );
            }

            foreach( $arrmixDeviceConfigJsonFileData['slv_devices'] as $arrmixSlaveDeviceData ) {
                
                if( $arrmixSlaveDeviceData['slv_id'] == $arrmixRequestData['slv_id'] ) {

                    $arrmixTempSlaveDeviceDetails = $arrmixRequestData;
                    array_map( 'intval', $arrmixTempSlaveDeviceDetails );
            
                    $arrmixTempSlaveDeviceDetails['data_type'] = $arrmixRequestData['data_type'];

                    $arrmixUpdatedSlaveDeviceList[] = $arrmixTempSlaveDeviceDetails;
                } else {
                    $arrmixUpdatedSlaveDeviceList[] = $arrmixSlaveDeviceData;
                }
            }
            
            $arrmixDeviceConfigJsonFileData['slv_devices'] = $arrmixUpdatedSlaveDeviceList;

            $this->g_objServiceLibrary->updateConfigFile( json_encode( $arrmixDeviceConfigJsonFileData ) );
            
            $this->session->setFlashdata( 'success', 'The Slave Id ' . $arrmixRequestData['slv_id'] . ' has been updated successfully.' );

            return redirect()->route( 'device-settings/com-settings/view' );
        }
        
        return $this->render( $arrmixData );
    }
    
    public function actionEditComSettings() {
        
        $arrmixRequestData = $this->request->getGet();
        
        if( false == isset( $arrmixRequestData['used_config_file'] ) || false == isValId( $arrmixRequestData['used_config_file'] ) ) {
            
            $this->session->setFlashdata( 'error', 'Unable to get config file.' );
            return redirect()->route( 'device-settings/com-settings/view' );
        }

        $intUsedConfigFile = $arrmixRequestData['used_config_file'];

        switch( $intUsedConfigFile ) {

            case USED_TEMP_CONFIG_FILE:
                $strConfigFileData = $this->g_objServiceLibrary->getConfigFile( TEMP_CONFIG_FILE_NAME );
                break;
            
            case USED_LATEST_CONFIG_FILE:
                $strConfigFileData = $this->g_objServiceLibrary->getConfigFile( LATEST_CONFIG_FILE_NAME );
                break;
            
            case USED_DEFAULT_CONFIG_FILE:
                $strConfigFileData = $this->g_objServiceLibrary->getConfigFile( DEFAULT_CONFIG_FILE_NAME );
                break;
            
            default:
                $strConfigFileData = $this->g_objServiceLibrary->getConfigFile( DEFAULT_CONFIG_FILE_NAME );
                break;
        }

        $arrmixDeviceConfigJsonFileData = json_decode( $strConfigFileData, true );

        $arrmixComSettingsDetails = [
            'mode'           => $arrmixDeviceConfigJsonFileData['rs485']['rs485_conf'],
            'baud_rate'      => $arrmixDeviceConfigJsonFileData['rs485']['br'],
            'data_bits'      => $arrmixDeviceConfigJsonFileData['rs485']['data_bit'],
            'parity_bits'    => $arrmixDeviceConfigJsonFileData['rs485']['par_bit'],
            'flow_control'   => $arrmixDeviceConfigJsonFileData['rs485']['fl_cntr'],
            'stop_bits'      => $arrmixDeviceConfigJsonFileData['rs485']['stop_bit']
        ];
        
        $arrmixBreadCrumbData['strContentHeader']     = 'Edit COM Port';
        $arrmixBreadCrumbData['arrmixBreadCrumbList'] = [
            ['name' => 'View COM Port', 'is_active' => false, 'href' => getBaseUrl() . 'device-settings/com-settings/view' ],
            ['name' => 'Edit COM Port Settings', 'is_active' => true]
        ];
        
        $arrmixData                 = [];
        $arrmixData['strTitle']     = 'Edit COM Port';
        $arrmixData['strCardTitle'] = 'Edit COM Port';
        $arrmixData['view']         = 'device-com-settings/converter-com-form-details';

        $arrmixData['arrmixBreadCrumbData']     = $arrmixBreadCrumbData;
        $arrmixData['arrmixComSettingsDetails'] = $arrmixComSettingsDetails;
        $arrmixData['intUsedConfigFile']        = $intUsedConfigFile;
        
        if( true == isValArr( $this->request->getPost() ) ) {
            
            $arrmixRequestData = $this->request->getPost();
            
            if( false == $this->validation->run( $arrmixRequestData , 'validateConverterComSettings' ) ) { 
                
                $this->session->setFlashdata( 'error', 'Validation Errors. Please check the below errors of com settings.' );
                self::setFormValidationErrors( $this->validation->getErrors() );
                
                return $this->render( $arrmixData );
            }

            $this->setConfigFileConverterSettingsData( $arrmixRequestData );
            
            $this->session->setFlashdata( 'success', 'Device com setting has been updated successfully.' );
            
            return redirect()->route( 'device-settings/com-settings/view' );
        }
        
        return $this->render( $arrmixData );
    }
    
    public function actionDeleteSlaveDevice() {
        
        $arrmixRequestData = $this->request->getPost();
        
        if( false == isset( $arrmixRequestData['slave_id'] ) || false == isValId( $arrmixRequestData['slave_id'] ) ) {
            $arrmixResponseData['success'] = false;
            $arrmixResponseData['message'] = 'Invalid Slave Id';
            
            $this->response( $arrmixResponseData );
            return true;
        }

        $arrmixResponseConfigData = $this->getConfigData();

        $arrmixDeviceConfigJsonFileData = $arrmixResponseConfigData['device_config_josn_file_data'];

        $arrmixUpdatedSlaveDeviceList = [];
        foreach( $arrmixDeviceConfigJsonFileData['slv_devices'] as $intKey => $arrmixSlaveDeviceDetails ) {
            
            if( $arrmixSlaveDeviceDetails['slv_id'] != $arrmixRequestData['slave_id'] ) {
                $arrmixUpdatedSlaveDeviceList[] = $arrmixSlaveDeviceDetails;
            }
        }

        $arrmixDeviceConfigJsonFileData['slv_devices'] = $arrmixUpdatedSlaveDeviceList;
        $this->g_objServiceLibrary->updateConfigFile( json_encode( $arrmixDeviceConfigJsonFileData ) );

        $arrmixResponseData['success'] = true;
        $arrmixResponseData['message'] = 'Slave Id ' . $arrmixRequestData['slave_id'] . ' has been deleted successfully.';

        $this->response( $arrmixResponseData );
    }  

    public function setConfigFileConverterSettingsData( $arrmixUpdateComSettingsData ) {
    
        $arrmixResponseConfigData = $this->getConfigData();

        $arrmixDeviceConfigJsonFileData = $arrmixResponseConfigData['device_config_josn_file_data'];

        $arrmixDeviceConfigJsonFileData['rs485']['rs485_conf'] = $arrmixUpdateComSettingsData['mode'];

        $this->g_objServiceLibrary->updateConfigFile( json_encode( $arrmixDeviceConfigJsonFileData ) );

        return true;
    }
}
