// 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 com.google.gwtorm.schema.QueryParser.Column;
import com.google.gwtorm.schema.sql.SqlBooleanTypeInfo;
import com.google.gwtorm.schema.sql.SqlDialect;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.Query;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.antlr.runtime.CommonToken;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.Tree;

public class QueryModel {
  private final RelationModel model;
  private final String name;
  private final Tree parsedQuery;

  public QueryModel(final RelationModel rel, final String queryName, final Query q)
      throws OrmException {
    this(rel, queryName, queryTextOf(queryName, q));
  }

  private static String queryTextOf(String queryName, Query q) throws OrmException {
    if (q == null) {
      throw new OrmException(
          "Query " + queryName + " is missing " + Query.class.getName() + " annotation");
    }
    return q.value();
  }

  public QueryModel(final RelationModel rel, final String queryName, final String queryText)
      throws OrmException {
    model = rel;
    name = queryName;

    try {
      parsedQuery = QueryParser.parse(model, queryText);
    } catch (QueryParseException e) {
      throw new OrmException("Cannot parse query " + queryText, e);
    }
  }

  public String getName() {
    return name;
  }

  public Tree getParseTree() {
    return parsedQuery;
  }

  public List<ColumnModel> getParameters() {
    final ArrayList<ColumnModel> r = new ArrayList<>();
    if (parsedQuery != null) {
      findParameters(r, parsedQuery);
    }
    return r;
  }

  public static class OrderBy {
    public final ColumnModel column;
    public final boolean descending;

    public OrderBy(ColumnModel column, boolean desc) {
      this.column = column;
      this.descending = desc;
    }

    @Override
    public int hashCode() {
      return column.hashCode();
    }

    @Override
    public boolean equals(Object other) {
      if (other instanceof OrderBy) {
        OrderBy o = (OrderBy) other;
        return column.equals(o.column) && descending == o.descending;
      }
      return false;
    }
  }

  public List<OrderBy> getOrderBy() {
    ArrayList<OrderBy> r = new ArrayList<>();
    if (parsedQuery != null) {
      Tree node = findOrderBy(parsedQuery);
      if (node != null) {
        for (int i = 0; i < node.getChildCount(); i++) {
          Tree sortOrder = node.getChild(i);
          Tree id = sortOrder.getChild(0);
          r.add(
              new OrderBy(
                  ((QueryParser.Column) id).getField(), sortOrder.getType() == QueryParser.DESC));
        }
      }
    }
    return r;
  }

  private void findParameters(final List<ColumnModel> r, final Tree node) {
    switch (node.getType()) {
      case QueryParser.WHERE:
        extractParameters(r, node);
        break;

      default:
        for (int i = 0; i < node.getChildCount(); i++) {
          findParameters(r, node.getChild(i));
        }
        break;
    }
  }

  private void extractParameters(final List<ColumnModel> r, final Tree node) {
    switch (node.getType()) {
      case QueryParser.LT:
      case QueryParser.LE:
      case QueryParser.GT:
      case QueryParser.GE:
      case QueryParser.EQ:
        if (node.getChild(1).getType() == QueryParser.PLACEHOLDER) {
          r.add(((QueryParser.Column) node.getChild(0)).getField());
        }
        break;

      default:
        for (int i = 0; i < node.getChildCount(); i++) {
          extractParameters(r, node.getChild(i));
        }
        break;
    }
  }

  public boolean hasWhere() {
    return findWhere(parsedQuery) != null;
  }

  public boolean hasOrderBy() {
    return findOrderBy(parsedQuery) != null;
  }

  public boolean hasLimit() {
    return findLimit(parsedQuery) != null;
  }

  public boolean hasLimitParameter() {
    final Tree limit = findLimit(parsedQuery);
    return limit != null && limit.getChild(0).getType() == QueryParser.PLACEHOLDER;
  }

  public int getStaticLimit() {
    return Integer.parseInt(findLimit(parsedQuery).getChild(0).getText());
  }

  private Tree findWhere(final Tree node) {
    if (node == null) {
      return null;
    }
    switch (node.getType()) {
      case QueryParser.WHERE:
        return node;
      default:
        for (int i = 0; i < node.getChildCount(); i++) {
          final Tree r = findLimit(node.getChild(i));
          if (r != null) {
            return r;
          }
        }
        return null;
    }
  }

  private Tree findLimit(final Tree node) {
    if (node == null) {
      return null;
    }
    switch (node.getType()) {
      case QueryParser.LIMIT:
        return node;
      default:
        for (int i = 0; i < node.getChildCount(); i++) {
          final Tree r = findLimit(node.getChild(i));
          if (r != null) {
            return r;
          }
        }
        return null;
    }
  }

  private Tree findOrderBy(final Tree node) {
    if (node == null) {
      return null;
    }
    switch (node.getType()) {
      case QueryParser.ORDER:
        return node;
      default:
        for (int i = 0; i < node.getChildCount(); i++) {
          final Tree r = findOrderBy(node.getChild(i));
          if (r != null) {
            return r;
          }
        }
        return null;
    }
  }

  public String getSelectSql(final SqlDialect dialect, final String tableAlias) {
    final StringBuilder buf = new StringBuilder();
    buf.append(model.getSelectSql(dialect, tableAlias));
    if (parsedQuery != null) {
      final FormatInfo fmt = new FormatInfo(buf, dialect, tableAlias);
      final Tree t = expand(parsedQuery);
      if (t.getType() == 0) {
        formatChilden(fmt, t);
      } else {
        format(fmt, t);
      }
    }
    return buf.toString();
  }

  private void formatChilden(final FormatInfo fmt, final Tree node) {
    for (int i = 0; i < node.getChildCount(); i++) {
      format(fmt, node.getChild(i));
    }
  }

  private void format(final FormatInfo fmt, final Tree node) {
    switch (node.getType()) {
      case QueryParser.WHERE:
        fmt.buf.append(" WHERE ");
        formatChilden(fmt, node);
        break;

      case QueryParser.AND:
        for (int i = 0; i < node.getChildCount(); i++) {
          if (i > 0) {
            fmt.buf.append(" AND ");
          }
          format(fmt, node.getChild(i));
        }
        break;

      case QueryParser.LT:
      case QueryParser.LE:
      case QueryParser.GT:
      case QueryParser.GE:
      case QueryParser.EQ:
        format(fmt, node.getChild(0));
        fmt.buf.append(node.getText());
        format(fmt, node.getChild(1));
        break;

      case QueryParser.ID:
        {
          final ColumnModel col = ((QueryParser.Column) node).getField();
          if (!col.isSqlPrimitive()) {
            throw new IllegalStateException("Unexpanded nested field");
          }
          fmt.buf.append(fmt.tableAlias);
          fmt.buf.append('.');
          fmt.buf.append(col.getColumnName());
          break;
        }

      case QueryParser.PLACEHOLDER:
        fmt.buf.append(fmt.dialect.getParameterPlaceHolder(fmt.nthParam++));
        break;

      case QueryParser.TRUE:
        fmt.buf.append(
            ((SqlBooleanTypeInfo) fmt.dialect.getSqlTypeInfo(Boolean.TYPE)).getTrueLiteralValue());
        break;

      case QueryParser.FALSE:
        fmt.buf.append(
            ((SqlBooleanTypeInfo) fmt.dialect.getSqlTypeInfo(Boolean.TYPE)).getFalseLiteralValue());
        break;

      case QueryParser.CONSTANT_INTEGER:
      case QueryParser.CONSTANT_STRING:
        fmt.buf.append(node.getText());
        break;

      case QueryParser.ORDER:
        fmt.buf.append(" ORDER BY ");
        for (int i = 0; i < node.getChildCount(); i++) {
          final Tree sortOrder = node.getChild(i);
          final Tree id = sortOrder.getChild(0);
          if (i > 0) {
            fmt.buf.append(',');
          }
          final ColumnModel col = ((QueryParser.Column) id).getField();
          if (col.isNested()) {
            for (final Iterator<ColumnModel> cItr = col.getAllLeafColumns().iterator();
                cItr.hasNext(); ) {
              fmt.buf.append(fmt.tableAlias);
              fmt.buf.append('.');
              fmt.buf.append(cItr.next().getColumnName());
              if (sortOrder.getType() == QueryParser.DESC) {
                fmt.buf.append(" DESC");
              }
              if (cItr.hasNext()) {
                fmt.buf.append(',');
              }
            }
          } else {
            fmt.buf.append(fmt.tableAlias);
            fmt.buf.append('.');
            fmt.buf.append(col.getColumnName());
            if (sortOrder.getType() == QueryParser.DESC) {
              fmt.buf.append(" DESC");
            }
          }
        }
        break;

      case QueryParser.LIMIT:
        if (fmt.dialect.selectHasLimit()) {
          final Tree p = node.getChild(0);
          if (p.getType() == QueryParser.CONSTANT_INTEGER
              || p.getType() == QueryParser.PLACEHOLDER) {
            fmt.buf.append(' ');
            fmt.buf.append(fmt.dialect.getLimitSql(p.getText()));
          }
        }
        break;

      default:
        throw new IllegalStateException("Unsupported query token");
    }
  }

  @Override
  public String toString() {
    return "Query[" + name + " " + getParseTree().toStringTree() + "]";
  }

  private Tree expand(final Tree node) {
    switch (node.getType()) {
      case QueryParser.LT:
      case QueryParser.LE:
      case QueryParser.GT:
      case QueryParser.GE:
      case QueryParser.EQ:
        {
          final Column qpc = (QueryParser.Column) node.getChild(0);
          final ColumnModel f = qpc.getField();
          if (f.isNested()) {
            final CommonTree join;

            join = new CommonTree(new CommonToken(QueryParser.AND));
            for (final ColumnModel c : f.getAllLeafColumns()) {
              final Tree op;

              op = node.dupNode();
              op.addChild(new QueryParser.Column(qpc, c));
              op.addChild(node.getChild(1).dupNode());
              join.addChild(op);
            }
            return join;
          }
        }
    }

    final Tree r = node.dupNode();
    for (int i = 0; i < node.getChildCount(); i++) {
      r.addChild(expand(node.getChild(i)));
    }
    return r;
  }

  static class FormatInfo {
    final StringBuilder buf;
    final SqlDialect dialect;
    final String tableAlias;
    int nthParam = 1;

    FormatInfo(StringBuilder r, SqlDialect dialect, String tableAlias) {
      this.buf = r;
      this.dialect = dialect;
      this.tableAlias = tableAlias;
    }
  }
}
