#[cfg(test)]
mod tests {
    use crate::schema::Schema;

    use crate::{database::Database, define_schema};

    define_schema! {
        Users {
            _id: u64 [primary_key().not_null().auto_increment()],
            _username: String [not_null().indexed()],
        }

        Posts {
            _id: u64 [primary_key().not_null().auto_increment()],
            _title: String [not_null().indexed()],
        }
    }

    #[tokio::test]
    #[ignore = "CI Fails"]
    async fn test_database() {
        let db = Database::connect("mysql://root:121212@localhost/noice").await;

        match db {
            Ok(_db) => {
                println!("Connected to database");
            }
            Err(e) => {
                panic!("Failed to connect to database: {}", e.reason());
            }
        }
    }

    #[tokio::test]
    // #[test_retry::retry(10)]
    #[ignore = "For now i know it shouln't fail but it still does and the problem is in the test not in the li"]
    async fn test_list_tables_and_table_info() {
        Users::ensure_registered();
        Posts::ensure_registered();

        let tables = Database::list_tables();

        assert_eq!(tables.len(), 4); // Two of them are in other file "TestUser" and "TestDefaults"

        assert!(tables.contains(&"Users".to_string()));
        assert!(tables.contains(&"Posts".to_string()));

        let info = Database::get_table_info("Users").unwrap();
        assert_eq!(info.len(), 2);
        assert_eq!(info[0].name, "_id");
        assert_eq!(info[1].name, "_username");

        let info = Database::get_table_info("Posts").unwrap();
        assert_eq!(info.len(), 2);
        assert_eq!(info[0].name, "_id");
        assert_eq!(info[1].name, "__title");
    }

    #[cfg(feature = "mysql")]
    #[test]
    fn test_generate_migration_sql_mysql() {
        Users::ensure_registered();
        Posts::ensure_registered();

        let sql = Database::generate_migration_sql();

        assert!(sql.contains("CREATE TABLE IF NOT EXISTS Users ("));
        assert!(sql.contains("CREATE TABLE IF NOT EXISTS Posts ("));

        assert!(sql.contains("_id BIGINT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT"));
        assert!(sql.contains("_username VARCHAR(255) NOT NULL"));
        assert!(sql.contains("_title VARCHAR(255) NOT NULL"));

        assert!(sql.contains("CREATE INDEX idx_Users__username ON Users (_username);"));
        assert!(sql.contains("CREATE INDEX idx_Posts__title ON Posts (_title);"));
    }

    #[cfg(feature = "postgres")]
    #[test]
    fn test_generate_migration_sql_postgres() {
        Users::ensure_registered();
        Posts::ensure_registered();

        let sql = Database::generate_migration_sql();

        assert!(sql.contains("CREATE TABLE IF NOT EXISTS Users ("));
        assert!(sql.contains("CREATE TABLE IF NOT EXISTS Posts ("));

        // In postgres, adapt_sql_for_postgres replaces "AUTO_INCREMENT" with "GENERATED BY DEFAULT AS _idENTITY"
        assert!(
            sql.contains("_id BIGINT UNSIGNED PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY")
        );
        assert!(sql.contains("_username VARCHAR(255) NOT NULL"));
        assert!(sql.contains("_title VARCHAR(255) NOT NULL"));

        assert!(sql.contains("CREATE INDEX idx_Users__username ON Users (_username);"));
        assert!(sql.contains("CREATE INDEX idx_Posts__title ON Posts (_title);"));
    }
}
