// Copyright (C) 2010 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.common.collect.ImmutableList;
import com.google.gerrit.index.query.AndPredicate;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryBuilder;
import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.ProjectWatches.ProjectWatchKey;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class IsWatchedByPredicate extends AndPredicate<ChangeData> {
  protected static String describe(CurrentUser user) {
    if (user.isIdentifiedUser()) {
      return user.getAccountId().toString();
    }
    return user.toString();
  }

  protected final CurrentUser user;

  public IsWatchedByPredicate(ChangeQueryBuilder.Arguments args) throws QueryParseException {
    super(filters(args));
    this.user = args.getUser();
  }

  protected static List<Predicate<ChangeData>> filters(ChangeQueryBuilder.Arguments args)
      throws QueryParseException {
    List<Predicate<ChangeData>> r = new ArrayList<>();
    ChangeQueryBuilder builder = new ChangeQueryBuilder(args);
    for (ProjectWatchKey w : getWatches(args)) {
      Predicate<ChangeData> f = null;
      if (w.filter() != null) {
        try {
          f = builder.parse(w.filter());
          if (QueryBuilder.find(f, IsWatchedByPredicate.class) != null) {
            // If the query is going to infinite loop, assume it
            // will never match and return null. Yes this test
            // prevents you from having a filter that matches what
            // another user is filtering on. :-)
            continue;
          }
        } catch (QueryParseException e) {
          continue;
        }
      }

      Predicate<ChangeData> p;
      if (w.project().equals(args.allProjectsName)) {
        p = null;
      } else {
        p = builder.project(w.project().get());
      }

      if (p != null && f != null) {
        r.add(and(p, f));
      } else if (p != null) {
        r.add(p);
      } else if (f != null) {
        r.add(f);
      } else {
        r.add(builder.statusOpen());
      }
    }
    if (r.isEmpty()) {
      return ImmutableList.of(ChangeIndexPredicate.none());
    } else {
      return ImmutableList.of(or(r));
    }
  }

  protected static Collection<ProjectWatchKey> getWatches(ChangeQueryBuilder.Arguments args)
      throws QueryParseException {
    CurrentUser user = args.getUser();
    if (user.isIdentifiedUser()) {
      return user.asIdentifiedUser().state().projectWatches().keySet();
    }
    return Collections.emptySet();
  }

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

  @Override
  public String toString() {
    String val = describe(user);
    if (val.indexOf(' ') < 0) {
      return ChangeQueryBuilder.FIELD_WATCHEDBY + ":" + val;
    }
    return ChangeQueryBuilder.FIELD_WATCHEDBY + ":\"" + val + "\"";
  }
}
