// 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.index.query;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.truth.ThrowableSubject;
import com.google.gerrit.testing.GerritBaseTests;
import java.util.Collection;
import java.util.Objects;
import org.junit.Test;

public class QueryBuilderTest extends GerritBaseTests {
  private static class TestPredicate extends Predicate<Object> {
    private final String field;
    private final String value;

    TestPredicate(String field, String value) {
      this.field = field;
      this.value = value;
    }

    @Override
    public Predicate<Object> copy(Collection<? extends Predicate<Object>> children) {
      throw new UnsupportedOperationException();
    }

    @Override
    public int hashCode() {
      return Objects.hash(field, value);
    }

    @Override
    public boolean equals(Object o) {
      if (!(o instanceof TestPredicate)) {
        return false;
      }
      TestPredicate p = (TestPredicate) o;
      return Objects.equals(field, p.field) && Objects.equals(value, p.value);
    }
  }

  private static class TestQueryBuilder extends QueryBuilder<Object, TestQueryBuilder> {
    TestQueryBuilder() {
      super(new QueryBuilder.Definition<>(TestQueryBuilder.class), null);
    }

    @Operator
    public Predicate<Object> a(String value) {
      return new TestPredicate("a", value);
    }
  }

  @Test
  public void fieldNameAndValue() throws Exception {
    assertThat(parse("a:foo")).isEqualTo(new TestPredicate("a", "foo"));
  }

  @Test
  public void fieldWithParenthesizedValues() throws Exception {
    assertThatParseException("a:(foo bar)").hasMessageThat().contains("no viable alternative");
  }

  @Test
  public void fieldNameAndValueThatLooksLikeFieldNameColonValue() throws Exception {
    assertThat(parse("a:foo:bar")).isEqualTo(new TestPredicate("a", "foo:bar"));
  }

  @Test
  public void fieldNameAndValueThatLooksLikeWordColonValue() throws Exception {
    assertThat(parse("a:*:bar")).isEqualTo(new TestPredicate("a", "*:bar"));
  }

  @Test
  public void fieldNameAndValueWithMultipleColons() throws Exception {
    assertThat(parse("a:*:*:*")).isEqualTo(new TestPredicate("a", "*:*:*"));
  }

  @Test
  public void exactPhraseWithQuotes() throws Exception {
    assertThat(parse("a:\"foo bar\"")).isEqualTo(new TestPredicate("a", "foo bar"));
  }

  @Test
  public void exactPhraseWithQuotesAndColon() throws Exception {
    assertThat(parse("a:\"foo:bar\"")).isEqualTo(new TestPredicate("a", "foo:bar"));
  }

  @Test
  public void exactPhraseWithBraces() throws Exception {
    assertThat(parse("a:{foo bar}")).isEqualTo(new TestPredicate("a", "foo bar"));
  }

  @Test
  public void exactPhraseWithBracesAndColon() throws Exception {
    assertThat(parse("a:{foo:bar}")).isEqualTo(new TestPredicate("a", "foo:bar"));
  }

  private static Predicate<Object> parse(String query) throws Exception {
    return new TestQueryBuilder().parse(query);
  }

  private static ThrowableSubject assertThatParseException(String query) {
    try {
      new TestQueryBuilder().parse(query);
      throw new AssertionError("expected QueryParseException for " + query);
    } catch (QueryParseException e) {
      return assertThat(e);
    }
  }
}
