use std::ops::Range;

use crate::{ParseError, Parser, ast::Ident, lexer::Token};

#[derive(Debug)]
pub struct CreateDatabaseStmt<'a> {
    pub span: Range<usize>,
    pub name: Ident<'a>,
}

impl<'a> Parser<'a> {
    /// Assumes that `create` has already been parsed and the span is set.
    #[instrument(skip_all, level = "trace")]
    pub(crate) fn parse_create_database_stmt(
        &mut self,
    ) -> Result<CreateDatabaseStmt<'a>, ParseError> {
        self.consume(&[Token::Database])?;
        let name = self.parse_ident()?;
        self.consume(&[Token::Semicolon])?;
        Ok(CreateDatabaseStmt {
            span: self.current_span.clone(),
            name,
        })
    }
}

#[cfg(test)]
mod tests {
    use crate::{ast::*, parse, tests::assert_no_errors};

    #[test]
    fn test_create_database() {
        let source = "create database mydb;";
        let (statements, errors) = parse(source);
        assert_no_errors(&errors);
        let Stmt::CreateDatabase(CreateDatabaseStmt { name, .. }) = &statements[0] else {
            panic!("invalid statement type: {:?}", &statements[0]);
        };
        assert_eq!(name.name, "mydb".into());
        assert_eq!(statements.len(), 1);
    }
}
