// 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.common.flogger.FluentLogger;
import com.google.gerrit.index.query.AndPredicate;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.ProjectWatches.ProjectWatchKey;
import com.google.gerrit.server.mail.send.ProjectWatch;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class IsWatchedByPredicate extends AndPredicate<ChangeData> {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  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<>();
    ProjectWatch.WatcherChangeQueryBuilder builder =
        new ProjectWatch.WatcherChangeQueryBuilder(args);
    for (ProjectWatchKey w : getWatches(args)) {
      Predicate<ChangeData> f = null;
      if (w.filter() != null) {
        try {
          f = builder.parse(w.filter());
        } catch (QueryParseException e) {
          logger.atFine().log(
              "Ignoring non-parseable filter of project watch %s: %s", w, e.getMessage());
          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());
    }
    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 + "\"";
  }
}
