# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

import json
import os
import shutil
import tempfile
import unittest
from io import StringIO
from unittest.mock import patch

import pyarrow as pa

from pypaimon import CatalogFactory, Schema
from pypaimon.cli.cli import main


class CliDbTest(unittest.TestCase):
    """Integration tests for CLI database commands with real catalog operations."""

    @classmethod
    def setUpClass(cls):
        """Set up test catalog and configuration."""
        cls.tempdir = tempfile.mkdtemp()
        cls.warehouse = os.path.join(cls.tempdir, 'warehouse')

        # Create catalog
        cls.catalog = CatalogFactory.create({
            'warehouse': cls.warehouse
        })

        # Create catalog config file
        cls.config_file = os.path.join(cls.tempdir, 'paimon.yaml')
        with open(cls.config_file, 'w') as f:
            f.write(f"metastore: filesystem\nwarehouse: {cls.warehouse}\n")

    @classmethod
    def tearDownClass(cls):
        """Clean up temporary directory."""
        shutil.rmtree(cls.tempdir, ignore_errors=True)

    def test_cli_db_create_basic(self):
        """Test basic database create via CLI."""
        with patch('sys.argv', ['paimon', '-c', self.config_file, 'db', 'create', 'new_db']):
            with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
                try:
                    main()
                except SystemExit:
                    pass

                output = mock_stdout.getvalue()
                self.assertIn('created successfully', output)

        # Verify database was created
        database = self.catalog.get_database('new_db')
        self.assertEqual(database.name, 'new_db')

    def test_cli_db_create_ignore_if_exists(self):
        """Test database create with ignore-if-exists flag."""
        # Create database first
        self.catalog.create_database('existing_db', True)

        # Try to create again with ignore-if-exists flag
        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'create', 'existing_db', '-i']):
            with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
                try:
                    main()
                except SystemExit:
                    pass

                output = mock_stdout.getvalue()
                self.assertIn('created successfully', output)

    def test_cli_db_create_already_exists_error(self):
        """Test database create raises error when database already exists."""
        self.catalog.create_database('dup_db', True)

        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'create', 'dup_db']):
            with patch('sys.stderr', new_callable=StringIO) as mock_stderr:
                with self.assertRaises(SystemExit) as context:
                    main()

                self.assertEqual(context.exception.code, 1)
                error_output = mock_stderr.getvalue()
                self.assertIn('Error', error_output)

    def test_cli_db_get_basic(self):
        """Test basic database get via CLI."""
        self.catalog.create_database('get_db', True)

        with patch('sys.argv', ['paimon', '-c', self.config_file, 'db', 'get', 'get_db']):
            with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
                try:
                    main()
                except SystemExit:
                    pass

                output = mock_stdout.getvalue()

                # Verify output is valid JSON
                result = json.loads(output)
                self.assertEqual(result['name'], 'get_db')
                self.assertIn('options', result)

    def test_cli_db_get_nonexistent(self):
        """Test CLI error handling for nonexistent database."""
        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'get', 'nonexistent_db']):
            with patch('sys.stderr', new_callable=StringIO) as mock_stderr:
                with self.assertRaises(SystemExit) as context:
                    main()

                self.assertEqual(context.exception.code, 1)
                error_output = mock_stderr.getvalue()
                self.assertIn('Error', error_output)

    def test_cli_db_drop_basic(self):
        """Test basic database drop via CLI."""
        self.catalog.create_database('drop_db', True)

        with patch('sys.argv', ['paimon', '-c', self.config_file, 'db', 'drop', 'drop_db']):
            with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
                try:
                    main()
                except SystemExit:
                    pass

                output = mock_stdout.getvalue()
                self.assertIn('dropped successfully', output)

        # Verify database was dropped
        from pypaimon.catalog.catalog_exception import DatabaseNotExistException
        with self.assertRaises(DatabaseNotExistException):
            self.catalog.get_database('drop_db')

    def test_cli_db_drop_nonexistent_error(self):
        """Test CLI error handling for dropping nonexistent database."""
        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'drop', 'nonexistent_drop_db']):
            with patch('sys.stderr', new_callable=StringIO) as mock_stderr:
                with self.assertRaises(SystemExit) as context:
                    main()

                self.assertEqual(context.exception.code, 1)
                error_output = mock_stderr.getvalue()
                self.assertIn('Error', error_output)

    def test_cli_db_drop_ignore_if_not_exists(self):
        """Test database drop with ignore-if-not-exists flag."""
        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'drop',
                    'nonexistent_ignore_db', '-i']):
            with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
                try:
                    main()
                except SystemExit:
                    pass

                output = mock_stdout.getvalue()
                self.assertIn('dropped successfully', output)

    def test_cli_db_drop_cascade(self):
        """Test database drop with cascade flag."""
        # Create database with a table
        self.catalog.create_database('cascade_db', True)

        pa_schema = pa.schema([
            ('id', pa.int32()),
            ('name', pa.string())
        ])
        schema = Schema.from_pyarrow_schema(pa_schema)
        self.catalog.create_table('cascade_db.test_table', schema, False)

        # Drop with cascade
        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'drop', 'cascade_db', '--cascade']):
            with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
                try:
                    main()
                except SystemExit:
                    pass

                output = mock_stdout.getvalue()
                self.assertIn('dropped successfully', output)

        # Verify database was dropped
        from pypaimon.catalog.catalog_exception import DatabaseNotExistException
        with self.assertRaises(DatabaseNotExistException):
            self.catalog.get_database('cascade_db')

    def test_cli_db_list_tables_basic(self):
        """Test basic list-tables via CLI."""
        # Create database with tables
        self.catalog.create_database('list_db', True)

        pa_schema = pa.schema([
            ('id', pa.int32()),
            ('value', pa.string())
        ])
        schema = Schema.from_pyarrow_schema(pa_schema)
        self.catalog.create_table('list_db.table_a', schema, True)
        self.catalog.create_table('list_db.table_b', schema, True)

        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'list-tables', 'list_db']):
            with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
                try:
                    main()
                except SystemExit:
                    pass

                output = mock_stdout.getvalue()
                self.assertIn('table_a', output)
                self.assertIn('table_b', output)

    def test_cli_db_list_tables_empty(self):
        """Test list-tables for empty database."""
        self.catalog.create_database('empty_list_db', True)

        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'list-tables', 'empty_list_db']):
            with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
                try:
                    main()
                except SystemExit:
                    pass

                output = mock_stdout.getvalue()
                self.assertIn('No tables found', output)

    def test_cli_db_list_tables_nonexistent_db(self):
        """Test list-tables for nonexistent database."""
        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'list-tables', 'nonexistent_list_db']):
            with patch('sys.stderr', new_callable=StringIO) as mock_stderr:
                with self.assertRaises(SystemExit) as context:
                    main()

                self.assertEqual(context.exception.code, 1)
                error_output = mock_stderr.getvalue()
                self.assertIn('Error', error_output)

    def test_cli_db_alter_not_supported(self):
        """Test db alter on filesystem catalog raises not supported error."""
        self.catalog.create_database('alter_db', True)

        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'alter', 'alter_db',
                    '--set', '{"key1": "value1"}']):
            with patch('sys.stderr', new_callable=StringIO) as mock_stderr:
                with self.assertRaises(SystemExit) as context:
                    main()

                self.assertEqual(context.exception.code, 1)
                error_output = mock_stderr.getvalue()
                self.assertIn('not supported', error_output)

    def test_cli_db_alter_no_changes(self):
        """Test db alter with no changes specified."""
        self.catalog.create_database('alter_no_change_db', True)

        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'alter', 'alter_no_change_db']):
            with patch('sys.stderr', new_callable=StringIO) as mock_stderr:
                with self.assertRaises(SystemExit) as context:
                    main()

                self.assertEqual(context.exception.code, 1)
                error_output = mock_stderr.getvalue()
                self.assertIn('No changes specified', error_output)

    def test_cli_db_alter_invalid_json(self):
        """Test db alter with invalid JSON for --set."""
        self.catalog.create_database('alter_invalid_db', True)

        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'db', 'alter', 'alter_invalid_db',
                    '--set', 'not_valid_json']):
            with patch('sys.stderr', new_callable=StringIO) as mock_stderr:
                with self.assertRaises(SystemExit) as context:
                    main()

                self.assertEqual(context.exception.code, 1)
                error_output = mock_stderr.getvalue()
                self.assertIn('Invalid JSON', error_output)

    def test_cli_catalog_list_dbs_basic(self):
        """Test basic list databases via catalog CLI."""
        self.catalog.create_database('list_db_a', True)
        self.catalog.create_database('list_db_b', True)

        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'catalog', 'list-dbs']):
            with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
                try:
                    main()
                except SystemExit:
                    pass

                output = mock_stdout.getvalue()
                self.assertIn('list_db_a', output)
                self.assertIn('list_db_b', output)

    def test_cli_catalog_list_dbs_excludes_nonexistent(self):
        """Test list databases does not include non-existent databases."""
        self.catalog.create_database('list_exists_db', True)

        with patch('sys.argv',
                   ['paimon', '-c', self.config_file, 'catalog', 'list-dbs']):
            with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
                try:
                    main()
                except SystemExit:
                    pass

                output = mock_stdout.getvalue()
                self.assertIn('list_exists_db', output)
                self.assertNotIn('never_created_db', output)


if __name__ == '__main__':
    unittest.main()
