// Copyright 2008 Google Inc.
//
// 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.gwtorm.schema;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import com.google.gwtorm.server.OrmException;

import org.antlr.runtime.tree.Tree;
import org.junit.Test;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;

public class QueryParserTest {
  private final class DummyColumn extends ColumnModel {
    private String name;

    DummyColumn(final int id, final String n) {
      columnId = id;
      name = n;
      columnName = n;
    }

    @Override
    public String getFieldName() {
      return name;
    }

    @Override
    public String getNestedClassName() {
      return null;
    }

    @Override
    public Class<?> getPrimitiveType() {
      return String.class;
    }

    @Override
    public Type[] getArgumentTypes() {
      return new Type[0];
    }

    @Override
    public boolean isCollection() {
      return false;
    }
  }

  protected Tree parse(final String str) throws QueryParseException {
    final RelationModel dummy = new RelationModel() {
      {
        final Collection<ColumnModel> c = new ArrayList<ColumnModel>();
        try {
          c.add(new DummyColumn(1, "name"));
          c.add(new DummyColumn(2, "a"));
          c.add(new DummyColumn(3, "b"));
          c.add(new DummyColumn(4, "c"));
          initColumns(c);
        } catch (OrmException e) {
          throw new RuntimeException("init columns failure", e);
        }
      }

      @Override
      public String getAccessInterfaceName() {
        return getClass().getName();
      }

      @Override
      public String getEntityTypeClassName() {
        return getClass().getName();
      }
    };
    return QueryParser.parse(dummy, str);
  }

  protected static void assertGoodEQ(final Tree c, final String fieldName) {
    assertEquals(QueryParser.EQ, c.getType());
    assertEquals(2, c.getChildCount());
    assertEquals(QueryParser.ID, c.getChild(0).getType());
    assertTrue(c.getChild(0) instanceof QueryParser.Column);
    assertEquals(fieldName, c.getChild(0).getText());
    assertEquals(QueryParser.PLACEHOLDER, c.getChild(1).getType());
  }

  @Test
  public void testEmptyQuery() throws QueryParseException {
    assertNull(parse(""));
  }

  @Test
  public void testWhereNameEq() throws QueryParseException {
    final Tree t = parse("WHERE name = ?");
    assertNotNull(t);
    assertEquals(QueryParser.WHERE, t.getType());

    assertEquals(1, t.getChildCount());
    assertGoodEQ(t.getChild(0), "name");
  }

  @Test
  public void testWhereAAndBAndC() throws QueryParseException {
    final Tree t = parse("WHERE a = ? AND b = ? AND c = ?");
    assertNotNull(t);
    assertEquals(QueryParser.WHERE, t.getType());

    assertEquals(1, t.getChildCount());
    final Tree c = t.getChild(0);
    assertEquals(QueryParser.AND, c.getType());
    assertEquals(3, c.getChildCount());
    assertGoodEQ(c.getChild(0), "a");
    assertGoodEQ(c.getChild(1), "b");
    assertGoodEQ(c.getChild(2), "c");
  }

  @Test
  public void testOrderByA() throws QueryParseException {
    final Tree t = parse("ORDER BY a");
    assertNotNull(t);
    assertEquals(QueryParser.ORDER, t.getType());
    assertEquals(1, t.getChildCount());

    final Tree a = t.getChild(0);
    assertEquals(QueryParser.ASC, a.getType());
    assertEquals(1, a.getChildCount());
    assertEquals(QueryParser.ID, a.getChild(0).getType());
    assertTrue(a.getChild(0) instanceof QueryParser.Column);
    assertEquals("a", a.getChild(0).getText());
  }

  @Test
  public void testOrderByAB() throws QueryParseException {
    final Tree t = parse("ORDER BY a DESC, b ASC");
    assertNotNull(t);
    assertEquals(QueryParser.ORDER, t.getType());
    assertEquals(2, t.getChildCount());
    {
      final Tree a = t.getChild(0);
      assertEquals(QueryParser.DESC, a.getType());
      assertEquals(1, a.getChildCount());
      assertEquals(QueryParser.ID, a.getChild(0).getType());
      assertTrue(a.getChild(0) instanceof QueryParser.Column);
      assertEquals("a", a.getChild(0).getText());
    }
    {
      final Tree b = t.getChild(1);
      assertEquals(QueryParser.ASC, b.getType());
      assertEquals(1, b.getChildCount());
      assertEquals(QueryParser.ID, b.getChild(0).getType());
      assertTrue(b.getChild(0) instanceof QueryParser.Column);
      assertEquals("b", b.getChild(0).getText());
    }
  }

  @Test
  public void testWhereAOrderByA() throws QueryParseException {
    final Tree t = parse("WHERE a = ? ORDER BY a");
    assertNotNull(t);
    assertEquals(0, t.getType());
    assertEquals(2, t.getChildCount());
    {
      final Tree w = t.getChild(0);
      assertEquals(QueryParser.WHERE, w.getType());
      assertEquals(1, w.getChildCount());
      assertGoodEQ(w.getChild(0), "a");
    }
    {
      final Tree o = t.getChild(1);
      assertEquals(QueryParser.ORDER, o.getType());
      assertEquals(1, o.getChildCount());

      final Tree a = o.getChild(0);
      assertEquals(QueryParser.ASC, a.getType());
      assertEquals(1, a.getChildCount());
      final Tree aId = a.getChild(0);
      assertEquals(QueryParser.ID, aId.getType());
      assertTrue(aId instanceof QueryParser.Column);
      assertEquals("a", aId.getText());
      assertEquals("a", ((QueryParser.Column) aId).getField().getFieldName());
    }
  }

  @Test
  public void testLimitWithConstant() throws QueryParseException {
    final Tree t = parse("LIMIT 1");
    assertNotNull(t);
    assertEquals(QueryParser.LIMIT, t.getType());
    assertEquals(1, t.getChildCount());
    {
      final Tree c = t.getChild(0);
      assertEquals(QueryParser.CONSTANT_INTEGER, c.getType());
    }
  }

  @Test
  public void testLimitWithPlaceholder() throws QueryParseException {
    final Tree t = parse("LIMIT ?");
    assertNotNull(t);
    assertEquals(QueryParser.LIMIT, t.getType());
    assertEquals(1, t.getChildCount());
    {
      final Tree c = t.getChild(0);
      assertEquals(QueryParser.PLACEHOLDER, c.getType());
    }
  }
}
