// 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.gerrit.reviewdb.AccountProjectWatch;
import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.query.OperatorPredicate;
import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException;
import com.google.gwtorm.client.OrmException;

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

class IsWatchedByPredicate extends OperatorPredicate<ChangeData> {
  private static String describe(CurrentUser user) {
    if (user instanceof IdentifiedUser) {
      return ((IdentifiedUser) user).getAccountId().toString();
    }
    return user.toString();
  }

  private final ChangeQueryBuilder.Arguments args;
  private final CurrentUser user;

  private Map<Project.NameKey, List<Predicate<ChangeData>>> rules;

  IsWatchedByPredicate(ChangeQueryBuilder.Arguments args, CurrentUser user) {
    super(ChangeQueryBuilder.FIELD_WATCHEDBY, describe(user));
    this.args = args;
    this.user = user;
  }

  @Override
  public boolean match(final ChangeData cd) throws OrmException {
    if (rules == null) {
      ChangeQueryBuilder builder = new ChangeQueryBuilder(args, user);
      rules = new HashMap<Project.NameKey, List<Predicate<ChangeData>>>();
      for (AccountProjectWatch w : user.getNotificationFilters()) {
        List<Predicate<ChangeData>> list = rules.get(w.getProjectNameKey());
        if (list == null) {
          list = new ArrayList<Predicate<ChangeData>>(4);
          rules.put(w.getProjectNameKey(), list);
        }

        Predicate<ChangeData> p = compile(builder, w);
        if (p != null) {
          list.add(p);
        }
      }
    }

    if (rules.isEmpty()) {
      return false;
    }

    Change change = cd.change(args.dbProvider);
    if (change == null) {
      return false;
    }

    Project.NameKey project = change.getDest().getParentKey();
    List<Predicate<ChangeData>> list = rules.get(project);
    if (list == null) {
      list = rules.get(args.wildProjectName);
    }
    if (list != null) {
      for (Predicate<ChangeData> p : list) {
        if (p.match(cd)) {
          return true;
        }
      }
    }
    return false;
  }

  @SuppressWarnings("unchecked")
  private Predicate<ChangeData> compile(ChangeQueryBuilder builder,
      AccountProjectWatch w) {
    Predicate<ChangeData> p = builder.is_visible();
    if (w.getFilter() != null) {
      try {
        p = Predicate.and(builder.parse(w.getFilter()), p);
        if (builder.find(p, 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. :-)
          //
          return null;
        }
        p = args.rewriter.get().rewrite(p);
      } catch (QueryParseException e) {
        return null;
      }
    }
    return p;
  }

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