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

use crate::dialect::Dialect;

/// A [`Dialect`] for [Databricks SQL](https://www.databricks.com/)
///
/// See <https://docs.databricks.com/en/sql/language-manual/index.html>.
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct DatabricksDialect;

impl Dialect for DatabricksDialect {
    // see https://docs.databricks.com/en/sql/language-manual/sql-ref-identifiers.html

    fn is_delimited_identifier_start(&self, ch: char) -> bool {
        matches!(ch, '`')
    }

    /// See <https://docs.databricks.com/en/sql/language-manual/sql-ref-identifiers.html>
    fn identifier_quote_style(&self, _identifier: &str) -> Option<char> {
        Some('`')
    }

    fn is_identifier_start(&self, ch: char) -> bool {
        matches!(ch, 'a'..='z' | 'A'..='Z' | '_')
    }

    fn is_identifier_part(&self, ch: char) -> bool {
        matches!(ch, 'a'..='z' | 'A'..='Z' | '0'..='9' | '_')
    }

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

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

    // https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select-groupby.html
    fn supports_group_by_expr(&self) -> bool {
        true
    }

    /// <https://docs.databricks.com/gcp/en/delta/history#delta-time-travel-syntax>
    fn supports_table_versioning(&self) -> bool {
        true
    }

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

    // https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select.html#syntax
    fn supports_select_wildcard_except(&self) -> bool {
        true
    }

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

    // See https://docs.databricks.com/en/sql/language-manual/functions/struct.html
    fn supports_struct_literal(&self) -> bool {
        true
    }

    /// See <https://docs.databricks.com/aws/en/sql/language-manual/sql-ref-syntax-comment>
    fn supports_nested_comments(&self) -> bool {
        true
    }

    /// See <https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select-groupby.html>
    fn supports_group_by_with_modifier(&self) -> bool {
        true
    }

    /// See <https://docs.databricks.com/en/sql/language-manual/sql-ref-syntax-qry-select-values.html>
    fn supports_values_as_table_factor(&self) -> bool {
        true
    }

    /// See <https://docs.databricks.com/en/sql/language-manual/delta-optimize.html>
    fn supports_optimize_table(&self) -> bool {
        true
    }

    /// See <https://docs.databricks.com/aws/en/sql/language-manual/functions/bangsign>
    fn supports_bang_not_operator(&self) -> bool {
        true
    }

    /// See <https://docs.databricks.com/aws/en/sql/language-manual/sql-ref-syntax-qry-select-cte>
    fn supports_cte_without_as(&self) -> bool {
        true
    }

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

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

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

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

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

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

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