<?php

namespace App\Controllers\CLI\DBMigration;

use CodeIgniter\Database\BaseConnection;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use App\Libraries\DBMigration\Process\ClientProcess;
use App\Libraries\DBMigration\Process\LineProcess;
use App\Libraries\DBMigration\Process\ServerCodeProcess;
use App\Libraries\DBMigration\Process\SWITCHCodeProcess;

abstract class BaseSource extends DBMigration
{
    private $_sourceDB = null;

    /**
     * SQL 쿼리 상수 정의
     */
    private const SQL_GET_CLIENT = "SELECT * FROM clientdb";
    private const SQL_GET_LINE = "SELECT * FROM linedb";
    private const SQL_GET_SERVER_CODE = "SELECT * FROM serverdb WHERE server_code NOT LIKE ?";
    private const SQL_GET_SWITCH_CODE = "SELECT * FROM servicedb WHERE service_sw NOT LIKE ?";

    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
    }
    abstract protected function getDBHost(): string;
    abstract protected function getDBUser(): string;
    abstract protected function getDBPassword(): string;
    abstract protected function getDBName(): string;
    /**
     * 소스 데이터베이스 연결 반환
     */
    final protected function getSourceDB(): BaseConnection
    {
        if ($this->_sourceDB === null) {
            $config = [
                'DSN'      => '',
                'hostname' => $this->getDBHost(),
                'username' => $this->getDBUser(),
                'password' => $this->getDBPassword(),
                'database' => $this->getDBName(),
                'DBDriver' => 'MySQLi',
                'DBPrefix' => '',
                'pConnect' => false,
                'DBDebug'  => (ENVIRONMENT !== 'production'),
                'cacheOn'  => false,
                'cacheDir' => '',
                'charset'  => 'utf8mb4',
                'DBCollat' => 'utf8mb4_general_ci',
                'swapPre'  => '',
                'encrypt'  => false,
                'compress' => false,
                'strictOn' => false,
                'failover' => [],
                'port'     => 3306,
            ];
            $this->_sourceDB = \Config\Database::connect($config);
        }
        return $this->_sourceDB;
    }
    /**
     * 공통 쿼리 실행 메서드
     */
    private function executeQuery(string $sql, array $params = []): array
    {
        return $this->getSourceDB()->query($sql, $params)->getResultArray();
    }

    protected function getClient(): array
    {
        return $this->executeQuery(self::SQL_GET_CLIENT);
    }

    protected function getLine(): array
    {
        return $this->executeQuery(self::SQL_GET_LINE);
    }

    protected function getServerCode(): array
    {
        return $this->executeQuery(self::SQL_GET_SERVER_CODE, ['%일회성%']);
    }

    protected function getSWITCHCode(): array
    {
        return $this->executeQuery(self::SQL_GET_SWITCH_CODE, ['%일회성%']);
    }

    //호출되는 함수
    final public function client(): void
    {
        $this->execute(
            new ClientProcess($this->getTargetDB()),
            $this->getClient(),
            __FUNCTION__,
            $this->getDBName()
        );
    }

    final public function line(): void
    {
        $this->execute(
            new LineProcess($this->getTargetDB()),
            $this->getLine(),
            __FUNCTION__,
            $this->getDBName()
        );
    }

    final public function servercode(): void
    {
        $this->execute(
            new ServerCodeProcess($this->getTargetDB()),
            $this->getServerCode(),
            __FUNCTION__,
            $this->getDBName()
        );
    }

    // final public function switchcode(): void
    // {
    //     $this->execute(
    //         new SWITCHCodeProcess($this->getTargetDB()),
    //         $this->getSWITCHCode(),
    //         __FUNCTION__,
    //         $this->getDBName()
    //     );
    // }
    final public function switchcode(): void
    {
        $processor = new SWITCHCodeProcess($this->getTargetDB());
        $processor->make();
    }
}
