import os
import sqlite3
import tempfile
import unittest

from sadb.configuration import SadbConfig
from sadb.database import APP_COLUMNS, ReadableDB, WritableDB


class LegacyDatabaseCompatibilityTests(unittest.TestCase):
    def setUp(self):
        self.temp_dir = tempfile.TemporaryDirectory()
        self.path = os.path.join(self.temp_dir.name, "legacy.db")
        columns = ", ".join(
            f"{column} text" for column in APP_COLUMNS if column != "appstream_name"
        )
        connection = sqlite3.connect(self.path)
        connection.execute(f"CREATE TABLE apps ({columns})")
        values = [None] * (len(APP_COLUMNS) - 1)
        values[0:2] = ["example", "Regular Name"]
        connection.execute(
            f"INSERT INTO apps VALUES ({','.join('?' for _ in values)})", values
        )
        connection.execute(
            "CREATE TABLE installed AS "
            "SELECT *, 0 AS update_available FROM apps WHERE 0"
        )
        connection.commit()
        connection.close()

        self.config = SadbConfig()
        self.config.db_location = self.path

    def tearDown(self):
        self.temp_dir.cleanup()

    def test_read_only_legacy_database_uses_regular_name(self):
        with ReadableDB(self.config) as database:
            projection = database.select_columns(
                "apps", ["id", "name", "appstream_name"]
            )
            row = database.c.execute(
                f"SELECT {projection} FROM apps"
            ).fetchone()
        self.assertEqual(row, ("example", "Regular Name", "Regular Name"))

    def test_writable_database_adds_and_backfills_appstream_name(self):
        with WritableDB(self.config) as database:
            self.assertTrue(database.has_column("apps", "appstream_name"))
            value = database.c.execute(
                "SELECT appstream_name FROM apps"
            ).fetchone()[0]
        self.assertEqual(value, "Regular Name")


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