<?php
/**
 * @copyright 2021 Double Bastion LLC <www.doublebastion.com>
 *
 * @author Double Bastion LLC
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

declare(strict_types=1);

namespace OCA\PaxFax\Service;

use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\Security\ICrypto;
use OCP\AppFramework\ApiController;
use OCP\IRequest;
use OCP\AppFramework\Controller;
use OCP\Files\IAppData;
use OCP\AppFramework\App;
use OCP\Files\NotPermittedException;
use OCP\Files\Folder;
use OC\Files\Filesystem;
use \ReflectionClass;

use Phaxio;
use Phaxio\OperationResult;
use Phaxio\Error\AuthenticationException;
use Phaxio\Error\NotFoundException;
use Phaxio\Error\InvalidRequestException;
use Phaxio\Error\RateLimitException;
use Phaxio\Error\APIConnectionException;
use Phaxio\Error\GeneralException;


class PaxfaxService {

      private $connection;

      private $crypto;

      public function __construct(IDBConnection $connection, ICrypto $crypto) {

              $this->connection = $connection;

              $this->crypto = $crypto;
      }


      /**
       * @NoAdminRequired
       */
      public function object_to_array($obj) {
         if(is_object($obj)) $obj = (array)$this->dismount($obj);
         if(is_array($obj)) {
            $new = array();
            foreach($obj as $key => $val) {
                $new[$key] = $this->object_to_array($val);
            }
         }
         else $new = $obj;
         return $new;
      }


      /**
       * @NoAdminRequired
       */
      public function dismount($object) {
         $reflectionClass = new ReflectionClass(get_class($object));
         $array = array();
         foreach ($reflectionClass->getProperties() as $property) {
            $property->setAccessible(true);
            $array[$property->getName()] = $property->getValue($object);
            $property->setAccessible(false);
         }
         return $array;
      }


      /**
       * @NoAdminRequired
       *
       */
      public function getsettings($userId) {

          $sql = $this->connection->prepare('
	           SELECT `id`, `user_id`, `api_key`, `api_secret`, `webhook_token`, `receive_url`, `sinch_project_id`, `sinch_key_id`, `sinch_key_secret`, `sinch_service_id`, `sinch_callback_url`, `get_notification`, `notification_email` 
                   FROM `*PREFIX*pax_fax`
                   WHERE `user_id` = ?');
	  $result = $sql->execute([$userId]);
          $settingsfromdb = $result->fetch();
          $result->closeCursor();

          if ($settingsfromdb) {

              if ($settingsfromdb['api_key'] != '') {

                  // Send a placeholder to the browser, instead of the real data
                  $settingsfromdb['api_key'] = "%20%20%20%20%20%20%20%20%20%20%20%20%20%20";
              }
              if ($settingsfromdb['api_secret'] != '') {
                  $settingsfromdb['api_secret'] = "%20%20%20%20%20%20%20%20%20%20%20%20%20%20";
              }
              if ($settingsfromdb['webhook_token'] != '') {
                  $settingsfromdb['webhook_token'] = "%20%20%20%20%20%20%20%20%20%20%20";
              }
              if ($settingsfromdb['receive_url'] != '') {
                  $settingsfromdb['receive_url']= "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20";
              }
              if ($settingsfromdb['sinch_project_id'] != '') {
                  $settingsfromdb['sinch_project_id'] = "%20%20%20%20%20%20%20%20%20%20%20%20";
              }
              if ($settingsfromdb['sinch_key_id'] != '') {
                  $settingsfromdb['sinch_key_id'] = "%20%20%20%20%20%20%20%20%20%20%20%20";
              }
              if ($settingsfromdb['sinch_key_secret'] != '') {
                  $settingsfromdb['sinch_key_secret'] = "%20%20%20%20%20%20%20%20%20%20%20%20";
              }
              if ($settingsfromdb['sinch_service_id'] != '') {
                  $settingsfromdb['sinch_service_id'] = "%20%20%20%20%20%20%20%20%20%20%20%20";
              }
              if ($settingsfromdb['sinch_callback_url'] != '') {
                  $settingsfromdb['sinch_callback_url'] = "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20";
              }
              return $settingsfromdb;
          }
      }


      /**
       * @NoAdminRequired
       *
       */
      public function updatesettings($userId, $apiKey, $apiSecret, $webhookToken, $receiveUrl, $sinchProjectId, $sinchKeyId, $sinchKeySecret, $sinchServiceId, $sinchCallbackUrl, $getNotification, $notificationEmail) {

          $sqlsel = $this->connection->prepare('
	             SELECT `id`, `user_id`, `api_key`, `api_secret`, `webhook_token`, `receive_url`, `sinch_project_id`, `sinch_key_id`, `sinch_key_secret`, `sinch_service_id`, `sinch_callback_url`, `get_notification`, `notification_email` 
                     FROM `*PREFIX*pax_fax`
                     WHERE `user_id` = ?');
	  $resultsel = $sqlsel->execute([$userId]);
          $row = $resultsel->fetch();
          $resultsel->closeCursor();

          if ($resultsel && !$row) {

              if ($apiKey != '') {
                  $apikeystrenc = $this->crypto->encrypt($apiKey);                
              } else { $apikeystrenc = ''; }

              if ($apiSecret != '') {
                  $apisecretstrenc = $this->crypto->encrypt($apiSecret);                
              } else { $apisecretstrenc = ''; }

              if ($webhookToken != '') {
                  $webhookTokenenc = $this->crypto->encrypt($webhookToken);               
              } else { $webhookTokenenc = ''; }

              if ($receiveUrl != '') {
                  $receiveUrlenc = $this->crypto->encrypt($receiveUrl);                
              } else { $receiveUrlenc = ''; }

              if ($sinchProjectId != '') {
                  $sinchProjectIdenc = $this->crypto->encrypt($sinchProjectId);                
              } else { $sinchProjectIdenc = ''; }

              if ($sinchKeyId != '') {
                  $sinchKeyIdenc = $this->crypto->encrypt($sinchKeyId);                
              } else { $sinchKeyIdenc = ''; }

              if ($sinchKeySecret != '') {
                  $sinchKeySecretenc = $this->crypto->encrypt($sinchKeySecret);                
              } else { $sinchKeySecretenc = ''; }

              if ($sinchServiceId != '') {
                  $sinchServiceIdenc = $this->crypto->encrypt($sinchServiceId);                
              } else { $sinchServiceIdenc = ''; }

              if ($sinchCallbackUrl != '') {
                  $sinchCallbackUrlenc = $this->crypto->encrypt($sinchCallbackUrl);                
              } else { $sinchCallbackUrlenc = ''; }

              $sqlns = $this->connection->prepare('
				INSERT INTO `*PREFIX*pax_fax`
					(`user_id`, `api_key`, `api_secret`, `webhook_token`, `receive_url`, `sinch_project_id`, `sinch_key_id`, `sinch_key_secret`, `sinch_service_id`, `sinch_callback_url`, `get_notification`, `notification_email`)
				VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
	      $sqlns->execute([$userId, $apikeystrenc, $apisecretstrenc, $webhookTokenenc, $receiveUrlenc, $sinchProjectIdenc, $sinchKeyIdenc, $sinchKeySecretenc, $sinchServiceIdenc, $sinchCallbackUrlenc, $getNotification, $notificationEmail]);

          } elseif ($resultsel && $row) {  

              if ($apiKey != '' && $apiKey != "%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $apikeystrenc = $this->crypto->encrypt($apiKey);                
              } elseif ($apiKey == "%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $apikeystrenc = $row['api_key'];
              } elseif ($apiKey == '') {
                  $apikeystrenc = '';
              }

              if ($apiSecret != '' && $apiSecret != "%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $apisecretstrenc = $this->crypto->encrypt($apiSecret);                
              } elseif ($apiSecret == "%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $apisecretstrenc = $row['api_secret'];
              } elseif ($apiSecret == '') {
                  $apisecretstrenc = '';
              }

              if ($webhookToken != '' && $webhookToken != "%20%20%20%20%20%20%20%20%20%20%20") {
                  $webhookTokenenc = $this->crypto->encrypt($webhookToken);                
              } elseif ($webhookToken == "%20%20%20%20%20%20%20%20%20%20%20") {
                  $webhookTokenenc = $row['webhook_token'];
              } elseif ($webhookToken == '') {
                  $webhookTokenenc = '';
              }

              if ($receiveUrl != '' && $receiveUrl != "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $receiveUrlenc = $this->crypto->encrypt($receiveUrl);                
              } elseif ($receiveUrl == "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $receiveUrlenc = $row['receive_url'];
              } elseif ($receiveUrl == '') {
                  $receiveUrlenc = '';
              }

              if ($sinchProjectId != '' && $sinchProjectId != "%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $sinchProjectIdenc = $this->crypto->encrypt($sinchProjectId);                
              } elseif ($sinchProjectId == "%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $sinchProjectIdenc = $row['sinch_project_id'];
              } elseif ($sinchProjectId == '') {
                  $sinchProjectIdenc = '';
              }

              if ($sinchKeyId != '' && $sinchKeyId != "%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $sinchKeyIdenc = $this->crypto->encrypt($sinchKeyId);                
              } elseif ($sinchKeyId == "%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $sinchKeyIdenc = $row['sinch_key_id'];
              } elseif ($sinchKeyId == '') {
                  $sinchKeyIdenc = '';
              }

              if ($sinchKeySecret != '' && $sinchKeySecret != "%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $sinchKeySecretenc = $this->crypto->encrypt($sinchKeySecret);                
              } elseif ($sinchKeySecret == "%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $sinchKeySecretenc = $row['sinch_key_secret'];
              } elseif ($sinchKeySecret == '') {
                  $sinchKeySecretenc = '';
              }

              if ($sinchServiceId != '' && $sinchServiceId != "%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $sinchServiceIdenc = $this->crypto->encrypt($sinchServiceId);                
              } elseif ($sinchServiceId == "%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $sinchServiceIdenc = $row['sinch_service_id'];
              } elseif ($sinchServiceId == '') {
                  $sinchServiceIdenc = '';
              }

              if ($sinchCallbackUrl != '' && $sinchCallbackUrl != "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $sinchCallbackUrlenc = $this->crypto->encrypt($sinchCallbackUrl);                
              } elseif ($sinchCallbackUrl == "%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20") {
                  $sinchCallbackUrlenc = $row['sinch_callback_url'];
              } elseif ($sinchCallbackUrl == '') {
                  $sinchCallbackUrlenc = '';
              }

	      $sqlup = $this->connection->prepare('
			UPDATE `*PREFIX*pax_fax`
			SET `api_key` = ?, `api_secret` = ?, `webhook_token` = ?, `receive_url` = ?, `sinch_project_id` = ?, `sinch_key_id` = ?, `sinch_key_secret` = ?, `sinch_service_id` = ?, `sinch_callback_url` = ?, `get_notification` = ?, `notification_email` = ?
                        WHERE `user_id` = ?');
	      $updateRes = $sqlup->execute([$apikeystrenc, $apisecretstrenc, $webhookTokenenc, $receiveUrlenc, $sinchProjectIdenc, $sinchKeyIdenc, $sinchKeySecretenc, $sinchServiceIdenc, $sinchCallbackUrlenc, $getNotification, $notificationEmail, $userId]);
	      $updateRes->closeCursor();
          }
      }

      /**
       * @NoAdminRequired
       */
      public function getapicredentials($userId) {

              $sqlselcr = $this->connection->prepare('
	                    SELECT `id`, `user_id`, `api_key`, `api_secret`, `webhook_token`, `receive_url`, `sinch_project_id`, `sinch_key_id`, `sinch_key_secret`, `sinch_service_id`, `sinch_callback_url`, `get_notification`, `notification_email` 
                            FROM `*PREFIX*pax_fax`
                            WHERE `user_id` = ?');
	      $resultselcr = $sqlselcr->execute([$userId]);
              $settingsfrdb = $resultselcr->fetch();
              $resultselcr->closeCursor();

              if (($settingsfrdb['api_key'] != '') && ($settingsfrdb['api_key'] != 'undefined') && ($settingsfrdb['api_key'] != null)) {
                   $apikeystr = $this->crypto->decrypt($settingsfrdb['api_key']);
              } else { $apikeystr = ''; }

              if (($settingsfrdb['api_secret'] != '') && ($settingsfrdb['api_secret'] != 'undefined') && ($settingsfrdb['api_secret'] != null)) {              
                   $apisecretstr = $this->crypto->decrypt($settingsfrdb['api_secret']);
              } else { $apisecretstr = ''; }

              if (($settingsfrdb['webhook_token'] != '') && ($settingsfrdb['webhook_token'] != 'undefined') && ($settingsfrdb['webhook_token'] != null)) {            
                   $webhookToken = $this->crypto->decrypt($settingsfrdb['webhook_token']);
              } else { $webhookToken = ''; }

              if (($settingsfrdb['receive_url'] != '') && ($settingsfrdb['receive_url'] != 'undefined') && ($settingsfrdb['receive_url'] != null)) {
                   $receiveUrl = $this->crypto->decrypt($settingsfrdb['receive_url']);
              } else { $receiveUrl = ''; }

              if (($settingsfrdb['sinch_project_id'] != '') && ($settingsfrdb['sinch_project_id'] != 'undefined') && ($settingsfrdb['sinch_project_id'] != null)) {
                   $sinchProjectId = $this->crypto->decrypt($settingsfrdb['sinch_project_id']);
              } else { $sinchProjectId = ''; }

              if (($settingsfrdb['sinch_key_id'] != '') && ($settingsfrdb['sinch_key_id'] != 'undefined') && ($settingsfrdb['sinch_key_id'] != null)) {
                   $sinchKeyId = $this->crypto->decrypt($settingsfrdb['sinch_key_id']);
              } else { $sinchKeyId = ''; }

              if (($settingsfrdb['sinch_key_secret'] != '') && ($settingsfrdb['sinch_key_secret'] != 'undefined') && ($settingsfrdb['sinch_key_secret'] != null)) {
                   $sinchKeySecret = $this->crypto->decrypt($settingsfrdb['sinch_key_secret']);
              } else { $sinchKeySecret = ''; }

              if (($settingsfrdb['sinch_service_id'] != '') && ($settingsfrdb['sinch_service_id'] != 'undefined') && ($settingsfrdb['sinch_service_id'] != null)) {
                   $sinchServiceId = $this->crypto->decrypt($settingsfrdb['sinch_service_id']);
              } else { $sinchServiceId = ''; }

              if (($settingsfrdb['sinch_callback_url'] != '') && ($settingsfrdb['sinch_callback_url'] != 'undefined') && ($settingsfrdb['sinch_callback_url'] != null)) {
                   $sinchCallbackUrl = $this->crypto->decrypt($settingsfrdb['sinch_callback_url']);
              } else { $sinchCallbackUrl = ''; }

              $getnotification = $settingsfrdb['get_notification'];
              $notifyemail = $settingsfrdb['notification_email'];

              return [$apikeystr, $apisecretstr, $webhookToken, $receiveUrl, $sinchProjectId, $sinchKeyId, $sinchKeySecret, $sinchServiceId, $sinchCallbackUrl, $getnotification, $notifyemail];
      }

}
