/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.hadoop.yarn.server.applicationhistoryservice.metrics.timeline.query;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.yarn.server.applicationhistoryservice.metrics.timeline.PhoenixHBaseAccessor;
import org.apache.hadoop.metrics2.sink.timeline.Precision;
import org.apache.hadoop.yarn.server.applicationhistoryservice.metrics.timeline.discovery.TimelineMetricMetadataManager;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class DefaultCondition implements Condition {
  List<String> metricNames;
  List<String> hostnames;
  String appId;
  String instanceId;
  Long startTime;
  Long endTime;
  Precision precision;
  Integer limit;
  boolean grouped;
  boolean noLimit = false;
  Integer fetchSize;
  String statement;
  Set<String> orderByColumns = new LinkedHashSet<String>();
  boolean metricNamesNotCondition = false;
  boolean hostNamesNotCondition = false;
  boolean uuidNotCondition = false;
  List<byte[]> uuids = new ArrayList<>();

  private static final Log LOG = LogFactory.getLog(DefaultCondition.class);

  public DefaultCondition(List<String> metricNames, List<String> hostnames, String appId,
                          String instanceId, Long startTime, Long endTime, Precision precision,
                          Integer limit, boolean grouped) {
    this.metricNames = metricNames;
    this.hostnames = hostnames;
    this.appId = appId;
    this.instanceId = instanceId;
    this.startTime = startTime;
    this.endTime = endTime;
    this.precision = precision;
    this.limit = limit;
    this.grouped = grouped;
  }

  public DefaultCondition(List<byte[]> uuids, List<String> metricNames, List<String> hostnames, String appId,
                          String instanceId, Long startTime, Long endTime, Precision precision,
                          Integer limit, boolean grouped) {
    this.uuids = uuids;
    this.metricNames = metricNames;
    this.hostnames = hostnames;
    this.appId = appId;
    this.instanceId = instanceId;
    this.startTime = startTime;
    this.endTime = endTime;
    this.precision = precision;
    this.limit = limit;
    this.grouped = grouped;
  }

  public String getStatement() {
    return statement;
  }

  public void setStatement(String statement) {
    this.statement = statement;
  }

  public List<String> getMetricNames() {
    return metricNames == null || metricNames.isEmpty() ? null : metricNames;
  }

  public StringBuilder getConditionClause() {
    StringBuilder sb = new StringBuilder();
    boolean appendConjunction = appendUuidClause(sb);
    appendConjunction = append(sb, appendConjunction, getStartTime(), " SERVER_TIME >= ?");
    append(sb, appendConjunction, getEndTime(), " SERVER_TIME < ?");

    return sb;
  }

  protected static boolean append(StringBuilder sb,
                                  boolean appendConjunction,
                                  Object value, String str) {
    if (value != null) {
      if (appendConjunction) {
        sb.append(" AND");
      }

      sb.append(str);
      appendConjunction = true;
    }
    return appendConjunction;
  }

  public List<String> getHostnames() {
    return hostnames;
  }

  public Precision getPrecision() {
    return precision;
  }

  public void setPrecision(Precision precision) {
    this.precision = precision;
  }

  public String getAppId() {
    if (appId != null && !appId.isEmpty()) {
      if (!(appId.equals("HOST") || appId.equals("FLUME_HANDLER"))) {
        return appId.toLowerCase();
      } else {
        return appId;
      }
    }
    return null;
  }

  public String getInstanceId() {
    return instanceId == null || instanceId.isEmpty() ? null : instanceId;
  }

  /**
   * Convert to millis.
   */
  public Long getStartTime() {
    if (startTime == null) {
      return null;
    } else if (startTime < 9999999999l) {
      return startTime * 1000;
    } else {
      return startTime;
    }
  }

  public Long getEndTime() {
    if (endTime == null) {
      return null;
    }
    if (endTime < 9999999999l) {
      return endTime * 1000;
    } else {
      return endTime;
    }
  }

  public void setNoLimit() {
    this.noLimit = true;
  }

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

  public Integer getLimit() {
    if (noLimit) {
      return null;
    }
    return limit == null ? PhoenixHBaseAccessor.RESULTSET_LIMIT : limit;
  }

  public boolean isGrouped() {
    return grouped;
  }

  public boolean isPointInTime() {
    return getStartTime() == null && getEndTime() == null;
  }

  public boolean isEmpty() {
    return (metricNames == null || metricNames.isEmpty())
      && (hostnames == null || hostnames.isEmpty())
      && (appId == null || appId.isEmpty())
      && (instanceId == null || instanceId.isEmpty())
      && startTime == null
      && endTime == null;
  }

  public Integer getFetchSize() {
    return fetchSize;
  }

  public void setFetchSize(Integer fetchSize) {
    this.fetchSize = fetchSize;
  }

  public void addOrderByColumn(String column) {
    orderByColumns.add(column);
  }

  public String getOrderByClause(boolean asc) {
    String orderByStr = " ORDER BY ";
    if (!orderByColumns.isEmpty()) {
      StringBuilder sb = new StringBuilder(orderByStr);
      for (String orderByColumn : orderByColumns) {
        if (sb.length() != orderByStr.length()) {
          sb.append(", ");
        }
        sb.append(orderByColumn);
        if (!asc) {
          sb.append(" DESC");
        }
      }
      sb.append(" ");
      return sb.toString();
    }
    return null;
  }

  protected boolean appendUuidClause(StringBuilder sb) {
    boolean appendConjunction = false;

    if (CollectionUtils.isNotEmpty(uuids)) {

      List<byte[]> uuidsHost = new ArrayList<>();
      List<byte[]> uuidsMetric = new ArrayList<>();
      List<byte[]> uuidsFull = new ArrayList<>();

      if (getUuids() != null) {
        for (byte[] uuid : uuids) {
          if (uuid.length == TimelineMetricMetadataManager.TIMELINE_METRIC_UUID_LENGTH) {
            uuidsMetric.add(uuid);
          } else if (uuid.length == TimelineMetricMetadataManager.HOSTNAME_UUID_LENGTH) {
            uuidsHost.add(uuid);
          } else {
            uuidsFull.add(uuid);
          }
        }

        // Put a '(' first
        sb.append("(");

        //IN clause
        // METRIC_NAME (NOT) IN (?,?,?,?)
        if (CollectionUtils.isNotEmpty(uuidsFull)) {
          sb.append("UUID");
          if (uuidNotCondition) {
            sb.append(" NOT");
          }
          sb.append(" IN (");
          //Append ?,?,?,?
          for (int i = 0; i < uuidsFull.size(); i++) {
            sb.append("?");
            if (i < uuidsFull.size() - 1) {
              sb.append(", ");
            }
          }
          sb.append(")");
          appendConjunction = true;
        }

        //Put an AND if both types are present
        if (CollectionUtils.isNotEmpty(uuidsFull) &&
          CollectionUtils.isNotEmpty(uuidsMetric)) {
          sb.append(" AND ");
        }

        // ( for OR
        if (!metricNamesNotCondition && uuidsMetric.size() > 1 && (CollectionUtils.isNotEmpty(uuidsFull) || CollectionUtils.isNotEmpty(uuidsHost))) {
          sb.append("(");
        }

        //LIKE clause for clusterMetric UUIDs
        // UUID (NOT) LIKE ? OR(AND) UUID LIKE ?
        if (CollectionUtils.isNotEmpty(uuidsMetric)) {

          for (int i = 0; i < uuidsMetric.size(); i++) {
            sb.append("UUID");
            if (metricNamesNotCondition) {
              sb.append(" NOT");
            }
            sb.append(" LIKE ");
            sb.append("?");

            if (i < uuidsMetric.size() - 1) {
              if (metricNamesNotCondition) {
                sb.append(" AND ");
              } else {
                sb.append(" OR ");
              }
            // ) for OR
            } else if ((CollectionUtils.isNotEmpty(uuidsFull) || CollectionUtils.isNotEmpty(uuidsHost)) && !metricNamesNotCondition && uuidsMetric.size() > 1) {
              sb.append(")");
            }
          }
          appendConjunction = true;
        }

        //Put an AND if both types are present
        if ((CollectionUtils.isNotEmpty(uuidsMetric) || (CollectionUtils.isNotEmpty(uuidsFull) && CollectionUtils.isEmpty(uuidsMetric)))
          && CollectionUtils.isNotEmpty(uuidsHost)) {
          sb.append(" AND ");
        }
        // ( for OR
        if((CollectionUtils.isNotEmpty(uuidsFull) || CollectionUtils.isNotEmpty(uuidsMetric)) && !hostNamesNotCondition && uuidsHost.size() > 1){
          sb.append("(");
        }

        //LIKE clause for HOST UUIDs
        // UUID (NOT) LIKE ? OR(AND) UUID LIKE ?
        if (CollectionUtils.isNotEmpty(uuidsHost)) {

          for (int i = 0; i < uuidsHost.size(); i++) {
            sb.append("UUID");
            if (hostNamesNotCondition) {
              sb.append(" NOT");
            }
            sb.append(" LIKE ");
            sb.append("?");

            if (i < uuidsHost.size() - 1) {
              if (hostNamesNotCondition) {
                sb.append(" AND ");
              } else {
                sb.append(" OR ");
              }
            // ) for OR
            } else if ((CollectionUtils.isNotEmpty(uuidsFull) || CollectionUtils.isNotEmpty(uuidsMetric)) && !hostNamesNotCondition && uuidsHost.size() > 1) {
              sb.append(")");
            }
          }
          appendConjunction = true;
        }

        // Finish with a ')'
        if (appendConjunction) {
          sb.append(")");
        }

        uuids = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(uuidsFull)) {
          uuids.addAll(uuidsFull);
        }
        for (byte[] uuid: uuidsMetric) {
          uuids.add(new String(uuid).concat("%").getBytes());
        }
        for (byte[] uuid: uuidsHost) {
          uuids.add("%".concat(new String(uuid)).getBytes());
        }
      }
    }

    return appendConjunction;
  }

  @Override
  public String toString() {
    return "Condition{" +
      "uuids=" + uuids +
      ", appId='" + appId + '\'' +
      ", instanceId='" + instanceId + '\'' +
      ", startTime=" + startTime +
      ", endTime=" + endTime +
      ", limit=" + limit +
      ", grouped=" + grouped +
      ", orderBy=" + orderByColumns +
      ", noLimit=" + noLimit +
      '}';
  }

  protected static boolean metricNamesHaveWildcard(List<String> metricNames) {
    for (String name : metricNames) {
      if (name.contains("%")) {
        return true;
      }
    }
    return false;
  }

  protected static boolean hostNamesHaveWildcard(List<String> hostnames) {
    if (hostnames == null)
      return false;
    for (String name : hostnames) {
      if (name.contains("%")) {
        return true;
      }
    }
    return false;
  }

  public void setMetricNamesNotCondition(boolean metricNamesNotCondition) {
    this.metricNamesNotCondition = metricNamesNotCondition;
  }

  @Override
  public void setHostnamesNotCondition(boolean hostNamesNotCondition) {
    this.hostNamesNotCondition = hostNamesNotCondition;
  }

  @Override
  public void setUuidNotCondition(boolean uuidNotCondition) {
    this.uuidNotCondition = uuidNotCondition;
  }

  @Override
  public List<byte[]> getUuids() {
    return uuids;
  }
}
