// Copyright (C) 2019 The Android Open Source Project
//
// Licensed 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.google.gerrit.plugins.checks;

import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.testing.GerritJUnit.assertThrows;

import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.testing.InMemoryModule;
import com.google.inject.Guice;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.junit.Test;

public class CheckerQueryTest {
  @Test
  public void emptyQuery() throws Exception {
    assertValidQuery("");
    assertValidQuery(" ");
    assertValidQuery(" \t ");
  }

  @Test
  public void invalidQueries() throws Exception {
    assertInvalidQuery("f", "Specific search operator required: f");
    assertInvalidQuery("\"foo bar\"", "Specific search operator required: foo bar");
    assertInvalidQuery("{foo bar}", "Specific search operator required: foo bar");
    assertInvalidQuery(
        "f:\"", "Invalid query: f:\"\nline 1:3 mismatched character '<EOF>' expecting '\"'");
  }

  @Test
  public void allowedOperators() throws Exception {
    assertValidQuery("f:foo");
    assertValidQuery("f:\"foo bar\"");
    assertValidQuery("f:{foo bar}");
    assertValidQuery("file:foo");
    assertValidQuery("hashtag:foo");
    assertValidQuery("status:foo");
  }

  @Test
  public void disallowedUnknownOperator() throws Exception {
    String query = "fhqwhgads:bar";
    assertThrows(QueryParseException.class, () -> newChangeQueryBuilder().parse(query));
    assertInvalidQuery(query, "Unsupported operator: fhqwhgads");
  }

  @Test
  public void disallowedButValidOperator() throws Exception {
    String query = "project:foo";
    assertThat(newChangeQueryBuilder().parse(query)).isNotNull();
    assertInvalidQuery(query, "Unsupported operator: project");
  }

  @Test
  public void andOperator() throws Exception {
    assertValidQuery("f:foo f:bar");
    assertValidQuery("f:foo AND f:bar");
    assertInvalidQuery("f:foo q:bar", "Unsupported operator: q");
    assertInvalidQuery("f:foo AND q:bar", "Unsupported operator: q");
    assertInvalidQuery("q:foo f:bar", "Unsupported operator: q");
    assertInvalidQuery("q:foo AND f:bar", "Unsupported operator: q");
  }

  @Test
  public void orOperator() throws Exception {
    assertValidQuery("f:foo OR f:bar");
    assertInvalidQuery("f:foo OR q:bar", "Unsupported operator: q");
    assertInvalidQuery("q:foo OR f:bar", "Unsupported operator: q");
  }

  @Test
  public void notOperator() throws Exception {
    assertValidQuery("-f:foo");
    assertInvalidQuery("-q:bar", "Unsupported operator: q");
  }

  @Test
  public void deeplyNestedQuery() throws Exception {
    assertValidQuery("(((f:foo f:bar) OR f:baz) -f:qux) OR f:quux");
    assertInvalidQuery("(((z:foo f:bar) OR f:baz) -f:qux) OR f:quux", "Unsupported operator: z");
    assertInvalidQuery("(((f:foo z:bar) OR f:baz) -f:qux) OR f:quux", "Unsupported operator: z");
    assertInvalidQuery("(((f:foo f:bar) OR z:baz) -f:qux) OR f:quux", "Unsupported operator: z");
    assertInvalidQuery("(((f:foo f:bar) OR f:baz) -z:qux) OR f:quux", "Unsupported operator: z");
    assertInvalidQuery("(((f:foo f:bar) OR f:baz) -f:qux) OR z:quux", "Unsupported operator: z");
  }

  private static void assertInvalidQuery(String query, String expectedMessage) {
    ConfigInvalidException thrown =
        assertThrows(ConfigInvalidException.class, () -> CheckerQuery.clean(query));
    assertThat(thrown).hasMessageThat().isEqualTo(expectedMessage);
  }

  private static void assertValidQuery(String query) {
    try {
      assertThat(CheckerQuery.clean(query)).isEqualTo(query.trim());
    } catch (ConfigInvalidException e) {
      throw new AssertionError("expected valid query: " + query, e);
    }
  }

  private static ChangeQueryBuilder newChangeQueryBuilder() {
    return Guice.createInjector(new InMemoryModule()).getInstance(ChangeQueryBuilder.class);
  }
}
