/*
 * 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.
 */
package com.datastax.driver.mapping;

import static org.assertj.core.api.Assertions.assertThat;

import org.testng.annotations.Test;

/** Test for JAVA-1316 - test combinations of different {@link NamingConventions} implementation. */
public class NamingConventionsTest {

  // test lower camel case inputs

  @Test(groups = "unit")
  public void lower_camel_case_to_upper_camel_case() {
    test(
        NamingConventions.LOWER_CAMEL_CASE,
        NamingConventions.UPPER_CAMEL_CASE,
        "myXmlParser",
        "MyXmlParser");
  }

  @Test(groups = "unit")
  public void lower_camel_case_to_lower_snake_case() {
    test(
        NamingConventions.LOWER_CAMEL_CASE,
        NamingConventions.LOWER_SNAKE_CASE,
        "myXmlParser",
        "my_xml_parser");
  }

  @Test(groups = "unit")
  public void lower_camel_case_to_upper_snake_case() {
    test(
        NamingConventions.LOWER_CAMEL_CASE,
        NamingConventions.UPPER_SNAKE_CASE,
        "myXmlParser",
        "MY_XML_PARSER");
  }

  @Test(groups = "unit")
  public void lower_camel_case_to_lower_lisp_case() {
    test(
        NamingConventions.LOWER_CAMEL_CASE,
        NamingConventions.LOWER_LISP_CASE,
        "myXmlParser",
        "my-xml-parser");
  }

  @Test(groups = "unit")
  public void lower_camel_case_to_upper_lisp_case() {
    test(
        NamingConventions.LOWER_CAMEL_CASE,
        NamingConventions.UPPER_LISP_CASE,
        "myXmlParser",
        "MY-XML-PARSER");
  }

  @Test(groups = "unit")
  public void lower_camel_case_to_lower_case() {
    test(
        NamingConventions.LOWER_CAMEL_CASE,
        NamingConventions.LOWER_CASE,
        "myXmlParser",
        "myxmlparser");
  }

  @Test(groups = "unit")
  public void lower_camel_case_to_upper_case() {
    test(
        NamingConventions.LOWER_CAMEL_CASE,
        NamingConventions.UPPER_CASE,
        "myXmlParser",
        "MYXMLPARSER");
  }

  // test upper camel case inputs

  @Test(groups = "unit")
  public void upper_camel_case_to_lower_camel_case() {
    test(
        NamingConventions.UPPER_CAMEL_CASE,
        NamingConventions.LOWER_CAMEL_CASE,
        "MyXmlParser",
        "myXmlParser");
  }

  @Test(groups = "unit")
  public void upper_camel_case_to_lower_snake_case() {
    test(
        NamingConventions.UPPER_CAMEL_CASE,
        NamingConventions.LOWER_SNAKE_CASE,
        "MyXmlParser",
        "my_xml_parser");
  }

  @Test(groups = "unit")
  public void upper_camel_case_to_upper_snake_case() {
    test(
        NamingConventions.UPPER_CAMEL_CASE,
        NamingConventions.UPPER_SNAKE_CASE,
        "MyXmlParser",
        "MY_XML_PARSER");
  }

  @Test(groups = "unit")
  public void upper_camel_case_to_lower_lisp_case() {
    test(
        NamingConventions.UPPER_CAMEL_CASE,
        NamingConventions.LOWER_LISP_CASE,
        "MyXmlParser",
        "my-xml-parser");
  }

  @Test(groups = "unit")
  public void upper_camel_case_to_upper_lisp_case() {
    test(
        NamingConventions.UPPER_CAMEL_CASE,
        NamingConventions.UPPER_LISP_CASE,
        "MyXmlParser",
        "MY-XML-PARSER");
  }

  @Test(groups = "unit")
  public void upper_camel_case_to_lower_case() {
    test(
        NamingConventions.UPPER_CAMEL_CASE,
        NamingConventions.LOWER_CASE,
        "MyXmlParser",
        "myxmlparser");
  }

  // test lower snake case inputs

  @Test(groups = "unit")
  public void lower_snake_case_to_lower_camel_case() {
    test(
        NamingConventions.LOWER_SNAKE_CASE,
        NamingConventions.LOWER_CAMEL_CASE,
        "my_xml_parser",
        "myXmlParser");
  }

  @Test(groups = "unit")
  public void lower_snake_case_to_upper_camel_case() {
    test(
        NamingConventions.LOWER_SNAKE_CASE,
        NamingConventions.UPPER_CAMEL_CASE,
        "my_xml_parser",
        "MyXmlParser");
  }

  @Test(groups = "unit")
  public void lower_snake_case_to_upper_snake_case() {
    test(
        NamingConventions.LOWER_SNAKE_CASE,
        NamingConventions.UPPER_SNAKE_CASE,
        "my_xml_parser",
        "MY_XML_PARSER");
  }

  @Test(groups = "unit")
  public void lower_snake_case_to_lower_lisp_case() {
    test(
        NamingConventions.LOWER_SNAKE_CASE,
        NamingConventions.LOWER_LISP_CASE,
        "my_xml_parser",
        "my-xml-parser");
  }

  @Test(groups = "unit")
  public void lower_snake_case_to_upper_lisp_case() {
    test(
        NamingConventions.LOWER_SNAKE_CASE,
        NamingConventions.UPPER_LISP_CASE,
        "my_xml_parser",
        "MY-XML-PARSER");
  }

  @Test(groups = "unit")
  public void lower_snake_case_to_lower_case() {
    test(
        NamingConventions.LOWER_SNAKE_CASE,
        NamingConventions.LOWER_CASE,
        "my_xml_parser",
        "myxmlparser");
  }

  // test upper snake case inputs

  @Test(groups = "unit")
  public void upper_snake_case_to_lower_camel_case() {
    test(
        NamingConventions.UPPER_SNAKE_CASE,
        NamingConventions.LOWER_CAMEL_CASE,
        "MY_XML_PARSER",
        "myXmlParser");
  }

  @Test(groups = "unit")
  public void upper_snake_case_to_upper_camel_case() {
    test(
        NamingConventions.UPPER_SNAKE_CASE,
        NamingConventions.UPPER_CAMEL_CASE,
        "MY_XML_PARSER",
        "MyXmlParser");
  }

  @Test(groups = "unit")
  public void upper_snake_case_to_lower_snake_case() {
    test(
        NamingConventions.UPPER_SNAKE_CASE,
        NamingConventions.LOWER_SNAKE_CASE,
        "MY_XML_PARSER",
        "my_xml_parser");
  }

  @Test(groups = "unit")
  public void upper_snake_case_to_lower_lisp_case() {
    test(
        NamingConventions.UPPER_SNAKE_CASE,
        NamingConventions.LOWER_LISP_CASE,
        "MY_XML_PARSER",
        "my-xml-parser");
  }

  @Test(groups = "unit")
  public void upper_snake_case_to_upper_lisp_case() {
    test(
        NamingConventions.UPPER_SNAKE_CASE,
        NamingConventions.UPPER_LISP_CASE,
        "MY_XML_PARSER",
        "MY-XML-PARSER");
  }

  @Test(groups = "unit")
  public void upper_snake_case_to_lower_case() {
    test(
        NamingConventions.UPPER_SNAKE_CASE,
        NamingConventions.LOWER_CASE,
        "MY_XML_PARSER",
        "myxmlparser");
  }

  // test lower lisp case inputs

  @Test(groups = "unit")
  public void lower_lisp_case_to_lower_camel_case() {
    test(
        NamingConventions.LOWER_LISP_CASE,
        NamingConventions.LOWER_CAMEL_CASE,
        "my-xml-parser",
        "myXmlParser");
  }

  @Test(groups = "unit")
  public void lower_lisp_case_to_upper_camel_case() {
    test(
        NamingConventions.LOWER_LISP_CASE,
        NamingConventions.UPPER_CAMEL_CASE,
        "my-xml-parser",
        "MyXmlParser");
  }

  @Test(groups = "unit")
  public void lower_lisp_case_to_lower_snake_case() {
    test(
        NamingConventions.LOWER_LISP_CASE,
        NamingConventions.LOWER_SNAKE_CASE,
        "my-xml-parser",
        "my_xml_parser");
  }

  @Test(groups = "unit")
  public void lower_lisp_case_to_upper_snake_case() {
    test(
        NamingConventions.LOWER_LISP_CASE,
        NamingConventions.UPPER_SNAKE_CASE,
        "my-xml-parser",
        "MY_XML_PARSER");
  }

  @Test(groups = "unit")
  public void lower_lisp_case_to_upper_lisp_case() {
    test(
        NamingConventions.LOWER_LISP_CASE,
        NamingConventions.UPPER_LISP_CASE,
        "my-xml-parser",
        "MY-XML-PARSER");
  }

  @Test(groups = "unit")
  public void lower_lisp_case_to_lower_case() {
    test(
        NamingConventions.LOWER_LISP_CASE,
        NamingConventions.LOWER_CASE,
        "my-xml-parser",
        "myxmlparser");
  }

  // test upper lisp case inputs

  @Test(groups = "unit")
  public void upper_lisp_case_to_lower_camel_case() {
    test(
        NamingConventions.UPPER_LISP_CASE,
        NamingConventions.LOWER_CAMEL_CASE,
        "MY-XML-PARSER",
        "myXmlParser");
  }

  @Test(groups = "unit")
  public void upper_lisp_case_to_upper_camel_case() {
    test(
        NamingConventions.UPPER_LISP_CASE,
        NamingConventions.UPPER_CAMEL_CASE,
        "MY-XML-PARSER",
        "MyXmlParser");
  }

  @Test(groups = "unit")
  public void upper_lisp_case_to_lower_snake_case() {
    test(
        NamingConventions.UPPER_LISP_CASE,
        NamingConventions.LOWER_SNAKE_CASE,
        "MY-XML-PARSER",
        "my_xml_parser");
  }

  @Test(groups = "unit")
  public void upper_lisp_case_to_upper_snake_case() {
    test(
        NamingConventions.UPPER_LISP_CASE,
        NamingConventions.UPPER_SNAKE_CASE,
        "MY-XML-PARSER",
        "MY_XML_PARSER");
  }

  @Test(groups = "unit")
  public void upper_lisp_case_to_lower_lisp_case() {
    test(
        NamingConventions.UPPER_LISP_CASE,
        NamingConventions.LOWER_LISP_CASE,
        "MY-XML-PARSER",
        "my-xml-parser");
  }

  @Test(groups = "unit")
  public void upper_lisp_case_to_lower_case() {
    test(
        NamingConventions.UPPER_LISP_CASE,
        NamingConventions.LOWER_CASE,
        "MY-XML-PARSER",
        "myxmlparser");
  }

  // test special camel case settings

  @Test(groups = "unit")
  public void lower_camel_case_with_prefix_to_upper_camel_case() {
    test(
        new NamingConventions.LowerCamelCase("_"),
        NamingConventions.UPPER_CAMEL_CASE,
        "_myXmlParser",
        "MyXmlParser");
    test(
        new NamingConventions.LowerCamelCase("_"),
        NamingConventions.UPPER_CAMEL_CASE,
        "myXmlParser",
        "MyXmlParser");
    test(
        new NamingConventions.LowerCamelCase("_", "m"),
        NamingConventions.UPPER_CAMEL_CASE,
        "mMyXmlParser",
        "MyXmlParser");
    test(
        new NamingConventions.LowerCamelCase("_", "m"),
        NamingConventions.UPPER_CAMEL_CASE,
        "_MyXmlParser",
        "MyXmlParser");
  }

  @Test(groups = "unit")
  public void lower_camel_case_with_prefix_to_lower_snake_case() {
    test(
        new NamingConventions.LowerCamelCase("_"),
        NamingConventions.LOWER_SNAKE_CASE,
        "_myXmlParser",
        "my_xml_parser");
    test(
        new NamingConventions.LowerCamelCase("_"),
        NamingConventions.LOWER_SNAKE_CASE,
        "myXmlParser",
        "my_xml_parser");
    test(
        new NamingConventions.LowerCamelCase("_", "m"),
        NamingConventions.LOWER_SNAKE_CASE,
        "mMyXmlParser",
        "my_xml_parser");
    test(
        new NamingConventions.LowerCamelCase("_", "m"),
        NamingConventions.LOWER_SNAKE_CASE,
        "_MyXmlParser",
        "my_xml_parser");
  }

  @Test(groups = "unit")
  public void upper_camel_case_with_prefix_to_upper_camel_case() {
    test(
        new NamingConventions.UpperCamelCase("_"),
        NamingConventions.UPPER_CAMEL_CASE,
        "_MyXmlParser",
        "MyXmlParser");
    test(
        new NamingConventions.UpperCamelCase("_"),
        NamingConventions.UPPER_CAMEL_CASE,
        "MyXmlParser",
        "MyXmlParser");
    test(
        new NamingConventions.UpperCamelCase("_", "m"),
        NamingConventions.UPPER_CAMEL_CASE,
        "mMyXmlParser",
        "MyXmlParser");
    test(
        new NamingConventions.UpperCamelCase("_", "m"),
        NamingConventions.UPPER_CAMEL_CASE,
        "_MyXmlParser",
        "MyXmlParser");
  }

  @Test(groups = "unit")
  public void upper_camel_case_with_prefix_to_upper_snake_case() {
    test(
        new NamingConventions.UpperCamelCase("_"),
        NamingConventions.LOWER_SNAKE_CASE,
        "_MyXmlParser",
        "my_xml_parser");
    test(
        new NamingConventions.UpperCamelCase("_"),
        NamingConventions.LOWER_SNAKE_CASE,
        "MyXmlParser",
        "my_xml_parser");
    test(
        new NamingConventions.UpperCamelCase("_", "m"),
        NamingConventions.LOWER_SNAKE_CASE,
        "mMyXmlParser",
        "my_xml_parser");
    test(
        new NamingConventions.UpperCamelCase("_", "m"),
        NamingConventions.LOWER_SNAKE_CASE,
        "_MyXmlParser",
        "my_xml_parser");
  }

  @Test(groups = "unit")
  public void lower_camel_case_with_abbr_to_lower_camel_case_with_no_abbr() {
    test(
        new NamingConventions.LowerCamelCase(true),
        new NamingConventions.LowerCamelCase(false),
        "myXMLParser",
        "myXmlParser");
  }

  @Test(groups = "unit")
  public void upper_camel_case_with_abbr_to_lower_camel_case_with_abbr() {
    test(
        new NamingConventions.UpperCamelCase(true),
        new NamingConventions.LowerCamelCase(true),
        "MyXMLParser",
        "myXMLParser");
  }

  private void test(
      NamingConvention inputConvention,
      NamingConvention outputConvention,
      String input,
      String output) {
    DefaultNamingStrategy namingStrategy =
        new DefaultNamingStrategy(inputConvention, outputConvention);
    String result = namingStrategy.toCassandraName(input);
    assertThat(result).isEqualTo(output);
  }
}
