// 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.

//! Test the ability for dialects to override parsing

use sqlparser::{
    ast::{BinaryOperator, Expr, Statement, Value},
    dialect::Dialect,
    keywords::Keyword,
    parser::{Parser, ParserError},
    test_utils::{expr_from_projection, only},
    tokenizer::Token,
};

#[test]
fn custom_prefix_parser() -> Result<(), ParserError> {
    #[derive(Debug)]
    struct MyDialect {}

    impl Dialect for MyDialect {
        fn is_identifier_start(&self, ch: char) -> bool {
            is_identifier_start(ch)
        }

        fn is_identifier_part(&self, ch: char) -> bool {
            is_identifier_part(ch)
        }

        fn parse_prefix(&self, parser: &mut Parser) -> Option<Result<Expr, ParserError>> {
            if parser.consume_token(&Token::Number("1".to_string(), false)) {
                Some(Ok(Expr::Value(Value::Null.with_empty_span())))
            } else {
                None
            }
        }
    }

    let dialect = MyDialect {};
    let sql = "SELECT 1 + 2";
    let ast = Parser::parse_sql(&dialect, sql)?;
    let query = &ast[0];
    assert_eq!("SELECT NULL + 2", &format!("{query}"));
    Ok(())
}

#[test]
fn custom_infix_parser() -> Result<(), ParserError> {
    #[derive(Debug)]
    struct MyDialect {}

    impl Dialect for MyDialect {
        fn is_identifier_start(&self, ch: char) -> bool {
            is_identifier_start(ch)
        }

        fn is_identifier_part(&self, ch: char) -> bool {
            is_identifier_part(ch)
        }

        fn parse_infix(
            &self,
            parser: &mut Parser,
            expr: &Expr,
            _precedence: u8,
        ) -> Option<Result<Expr, ParserError>> {
            if parser.consume_token(&Token::Plus) {
                Some(Ok(Expr::BinaryOp {
                    left: Box::new(expr.clone()),
                    op: BinaryOperator::Multiply, // translate Plus to Multiply
                    right: Box::new(parser.parse_expr().unwrap()),
                }))
            } else {
                None
            }
        }
    }

    let dialect = MyDialect {};
    let sql = "SELECT 1 + 2";
    let ast = Parser::parse_sql(&dialect, sql)?;
    let query = &ast[0];
    assert_eq!("SELECT 1 * 2", &format!("{query}"));
    Ok(())
}

#[test]
fn custom_statement_parser() -> Result<(), ParserError> {
    #[derive(Debug)]
    struct MyDialect {}

    impl Dialect for MyDialect {
        fn is_identifier_start(&self, ch: char) -> bool {
            is_identifier_start(ch)
        }

        fn is_identifier_part(&self, ch: char) -> bool {
            is_identifier_part(ch)
        }

        fn parse_statement(&self, parser: &mut Parser) -> Option<Result<Statement, ParserError>> {
            if parser.parse_keyword(Keyword::SELECT) {
                for _ in 0..3 {
                    let _ = parser.next_token();
                }
                Some(Ok(Statement::Commit {
                    chain: false,
                    end: false,
                    modifier: None,
                }))
            } else {
                None
            }
        }
    }

    let dialect = MyDialect {};
    let sql = "SELECT 1 + 2";
    let ast = Parser::parse_sql(&dialect, sql)?;
    let query = &ast[0];
    assert_eq!("COMMIT", &format!("{query}"));
    Ok(())
}

#[test]
fn test_map_syntax_not_support_default() -> Result<(), ParserError> {
    #[derive(Debug)]
    struct MyDialect {}

    impl Dialect for MyDialect {
        fn is_identifier_start(&self, ch: char) -> bool {
            is_identifier_start(ch)
        }

        fn is_identifier_part(&self, ch: char) -> bool {
            is_identifier_part(ch)
        }
    }

    let dialect = MyDialect {};
    let sql = "SELECT MAP {1: 2}";
    let ast = Parser::parse_sql(&dialect, sql);
    assert!(ast.is_err());
    Ok(())
}

fn is_identifier_start(ch: char) -> bool {
    ch.is_ascii_lowercase() || ch.is_ascii_uppercase() || ch == '_'
}

fn is_identifier_part(ch: char) -> bool {
    ch.is_ascii_lowercase()
        || ch.is_ascii_uppercase()
        || ch.is_ascii_digit()
        || ch == '$'
        || ch == '_'
}

#[test]
fn custom_dialect_lambda_keyword_syntax_without_arrow() {
    // A dialect that gives `->` its own meaning can still support lambdas
    // through the `LAMBDA` keyword spelling.
    #[derive(Debug)]
    struct MyDialect {}

    impl Dialect for MyDialect {
        fn is_identifier_start(&self, ch: char) -> bool {
            is_identifier_start(ch)
        }

        fn is_identifier_part(&self, ch: char) -> bool {
            is_identifier_part(ch)
        }

        fn supports_lambda_keyword_syntax(&self) -> bool {
            true
        }
    }

    let dialect = MyDialect {};

    // The `LAMBDA` spelling parses.
    let sql = "SELECT transform(xs, lambda x : x + 1)";
    assert_eq!(
        sql,
        &format!("{}", Parser::parse_sql(&dialect, sql).unwrap()[0])
    );

    // `->` keeps whatever meaning the dialect gives it, rather than
    // introducing a lambda parameter.
    let sql = "SELECT a -> 'b'";
    let ast = Parser::parse_sql(&dialect, sql).unwrap();
    match &ast[0] {
        Statement::Query(query) => {
            let Expr::BinaryOp { op, .. } =
                expr_from_projection(only(&query.body.as_select().unwrap().projection))
            else {
                panic!("expected `->` to stay a binary operator");
            };
            assert_eq!(&BinaryOperator::Arrow, op);
        }
        stmt => panic!("unexpected statement {stmt}"),
    }
}

#[test]
fn custom_dialect_lambda_keyword_defaults_to_arrow_support() {
    // Dialects that opt into the `->` spelling get the `LAMBDA` spelling too,
    // so the new capability does not change any existing dialect.
    #[derive(Debug)]
    struct MyDialect {}

    impl Dialect for MyDialect {
        fn is_identifier_start(&self, ch: char) -> bool {
            is_identifier_start(ch)
        }

        fn is_identifier_part(&self, ch: char) -> bool {
            is_identifier_part(ch)
        }

        fn supports_lambda_functions(&self) -> bool {
            true
        }
    }

    let dialect = MyDialect {};
    assert!(dialect.supports_lambda_keyword_syntax());
    for sql in [
        "SELECT transform(xs, lambda x : x + 1)",
        "SELECT transform(xs, x -> x + 1)",
    ] {
        assert_eq!(
            sql,
            &format!("{}", Parser::parse_sql(&dialect, sql).unwrap()[0])
        );
    }
}

#[test]
fn custom_dialect_lambda_arrow_syntax_without_keyword() {
    // Arrow lambdas stay on while the `LAMBDA` keyword spelling is off,
    // as in engines like Spark and Snowflake.
    #[derive(Debug)]
    struct MyDialect {}

    impl Dialect for MyDialect {
        fn is_identifier_start(&self, ch: char) -> bool {
            is_identifier_start(ch)
        }

        fn is_identifier_part(&self, ch: char) -> bool {
            is_identifier_part(ch)
        }

        fn supports_lambda_functions(&self) -> bool {
            true
        }

        fn supports_lambda_keyword_syntax(&self) -> bool {
            false
        }
    }

    let dialect = MyDialect {};

    let sql = "SELECT transform(xs, x -> x + 1)";
    assert_eq!(
        sql,
        &format!("{}", Parser::parse_sql(&dialect, sql).unwrap()[0])
    );
    assert!(Parser::parse_sql(&dialect, "SELECT transform(xs, lambda x : x + 1)").is_err());
}
