// Copyright (C) 2009 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.server.query.change;

import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.server.query.OperatorPredicate;
import com.google.gerrit.server.query.Predicate;
import com.google.gwtorm.client.OrmException;
import com.google.inject.Provider;

import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * Predicate for a {@link Change.Status}.
 * <p>
 * The actual name of this operator can differ, it usually comes as {@code
 * status:} but may also be {@code is:} to help do-what-i-meanery for end-users
 * searching for changes. Either operator name has the same meaning.
 */
final class ChangeStatusPredicate extends OperatorPredicate<ChangeData> {
  private static final Map<String, Change.Status> byName;
  private static final EnumMap<Change.Status, String> byEnum;

  static {
    byName = new HashMap<String, Change.Status>();
    byEnum = new EnumMap<Change.Status, String>(Change.Status.class);
    for (final Change.Status s : Change.Status.values()) {
      final String name = s.name().toLowerCase();
      byName.put(name, s);
      byEnum.put(s, name);
    }
  }

  static Predicate<ChangeData> open(Provider<ReviewDb> dbProvider) {
    List<Predicate<ChangeData>> r = new ArrayList<Predicate<ChangeData>>(4);
    for (final Change.Status e : Change.Status.values()) {
      if (e.isOpen()) {
        r.add(new ChangeStatusPredicate(dbProvider, e));
      }
    }
    return r.size() == 1 ? r.get(0) : or(r);
  }

  static Predicate<ChangeData> closed(Provider<ReviewDb> dbProvider) {
    List<Predicate<ChangeData>> r = new ArrayList<Predicate<ChangeData>>(4);
    for (final Change.Status e : Change.Status.values()) {
      if (e.isClosed()) {
        r.add(new ChangeStatusPredicate(dbProvider, e));
      }
    }
    return r.size() == 1 ? r.get(0) : or(r);
  }

  private static Change.Status parse(final String value) {
    final Change.Status s = byName.get(value);
    if (s == null) {
      throw new IllegalArgumentException();
    }
    return s;
  }

  private final Provider<ReviewDb> dbProvider;
  private final Change.Status status;

  ChangeStatusPredicate(Provider<ReviewDb> dbProvider, String value) {
    this(dbProvider, parse(value));
  }

  ChangeStatusPredicate(Provider<ReviewDb> dbProvider, Change.Status status) {
    super(ChangeQueryBuilder.FIELD_STATUS, byEnum.get(status));
    this.dbProvider = dbProvider;
    this.status = status;
  }

  Change.Status getStatus() {
    return status;
  }

  @Override
  public boolean match(final ChangeData object) throws OrmException {
    Change change = object.change(dbProvider);
    return change != null && status.equals(change.getStatus());
  }

  @Override
  public int getCost() {
    return 0;
  }

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

  @Override
  public boolean equals(Object other) {
    if (other instanceof ChangeStatusPredicate) {
      final ChangeStatusPredicate p = (ChangeStatusPredicate) other;
      return status.equals(p.status);
    }
    return false;
  }

  @Override
  public String toString() {
    return getOperator() + ":" + getValue();
  }
}
