<?php

namespace MintyPHP\Tests\Support;

use MintyPHP\Support\SqlStatementParser;
use PHPUnit\Framework\TestCase;
use RuntimeException;

class SqlStatementParserTest extends TestCase
{
    public function testBasicSplitting(): void
    {
        $sql = "CREATE TABLE foo (id INT);\nINSERT INTO foo VALUES (1);";
        $result = SqlStatementParser::splitStatements($sql);

        $this->assertCount(2, $result);
        $this->assertSame('CREATE TABLE foo (id INT)', $result[0]);
        $this->assertSame('INSERT INTO foo VALUES (1)', $result[1]);
    }

    public function testSemicolonInsideSingleQuotedString(): void
    {
        $sql = "INSERT INTO foo VALUES ('a;b');";
        $result = SqlStatementParser::splitStatements($sql);

        $this->assertCount(1, $result);
        $this->assertSame("INSERT INTO foo VALUES ('a;b')", $result[0]);
    }

    public function testSemicolonInsideDoubleQuotedString(): void
    {
        $sql = 'INSERT INTO foo VALUES ("a;b");';
        $result = SqlStatementParser::splitStatements($sql);

        $this->assertCount(1, $result);
        $this->assertSame('INSERT INTO foo VALUES ("a;b")', $result[0]);
    }

    public function testSemicolonInsideBackticks(): void
    {
        $sql = "SELECT `col;name` FROM foo;";
        $result = SqlStatementParser::splitStatements($sql);

        $this->assertCount(1, $result);
        $this->assertSame('SELECT `col;name` FROM foo', $result[0]);
    }

    public function testLineComments(): void
    {
        $sql = "-- this is a comment\nSELECT 1;\n# another comment\nSELECT 2;";
        $result = SqlStatementParser::splitStatements($sql);

        $this->assertCount(2, $result);
    }

    public function testBlockComments(): void
    {
        $sql = "SELECT /* ; not a delimiter */ 1;";
        $result = SqlStatementParser::splitStatements($sql);

        $this->assertCount(1, $result);
        $this->assertSame('SELECT /* ; not a delimiter */ 1', $result[0]);
    }

    public function testDelimiterDirectiveThrows(): void
    {
        $this->expectException(RuntimeException::class);
        $this->expectExceptionMessage('DELIMITER');

        SqlStatementParser::splitStatements("DELIMITER //\nCREATE PROCEDURE foo() BEGIN END//\nDELIMITER ;");
    }

    public function testEmptyInput(): void
    {
        $this->assertSame([], SqlStatementParser::splitStatements(''));
        $this->assertSame([], SqlStatementParser::splitStatements('   '));
        $this->assertSame([], SqlStatementParser::splitStatements(";\n;"));
    }

    public function testTrailingStatementWithoutSemicolon(): void
    {
        $sql = "SELECT 1; SELECT 2";
        $result = SqlStatementParser::splitStatements($sql);

        $this->assertCount(2, $result);
        $this->assertSame('SELECT 1', $result[0]);
        $this->assertSame('SELECT 2', $result[1]);
    }

    public function testEscapedQuotesInString(): void
    {
        $sql = "INSERT INTO foo VALUES ('it\\'s;here');";
        $result = SqlStatementParser::splitStatements($sql);

        $this->assertCount(1, $result);
    }
}
