// 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 org.antlr.runtime.CommonToken;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.Tree;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

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<ColumnModel>();
    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<OrderBy>();
    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(" LIMIT ");
            fmt.buf.append(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;
    }
  }
}
