// Copyright (C) 2016 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.account;

import static com.google.common.base.MoreObjects.firstNonNull;
import static java.util.Objects.requireNonNull;

import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Enums;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder;
import com.google.common.collect.Sets;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.git.ValidationError;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jgit.lib.Config;

/**
 * Parses/writes project watches from/to a {@link Config} file.
 *
 * <p>This is a low-level API. Read/write of project watches in a user branch should be done through
 * {@link AccountsUpdate} or {@link AccountConfig}.
 *
 * <p>The config file has one 'project' section for all project watches of a project.
 *
 * <p>The project name is used as subsection name and the filters with the notify types that decide
 * for which events email notifications should be sent are represented as 'notify' values in the
 * subsection. A 'notify' value is formatted as {@code <filter>
 * [<comma-separated-list-of-notify-types>]}:
 *
 * <pre>
 *   [project "foo"]
 *     notify = * [ALL_COMMENTS]
 *     notify = branch:master [ALL_COMMENTS, NEW_PATCHSETS]
 *     notify = branch:master owner:self [SUBMITTED_CHANGES]
 * </pre>
 *
 * <p>If two notify values in the same subsection have the same filter they are merged on the next
 * save, taking the union of the notify types.
 *
 * <p>For watch configurations that notify on no event the list of notify types is empty:
 *
 * <pre>
 *   [project "foo"]
 *     notify = branch:master []
 * </pre>
 *
 * <p>Unknown notify types are ignored and removed on save.
 *
 * <p>The project watches are lazily parsed.
 */
public class ProjectWatches {
  @AutoValue
  public abstract static class ProjectWatchKey {

    public static ProjectWatchKey create(Project.NameKey project, @Nullable String filter) {
      return new AutoValue_ProjectWatches_ProjectWatchKey(project, Strings.emptyToNull(filter));
    }

    public abstract Project.NameKey project();

    public abstract @Nullable String filter();
  }

  public enum NotifyType {
    // sort by name, except 'ALL' which should stay last
    ABANDONED_CHANGES,
    ALL_COMMENTS,
    NEW_CHANGES,
    NEW_PATCHSETS,
    SUBMITTED_CHANGES,

    ALL
  }

  public static final String FILTER_ALL = "*";

  public static final String WATCH_CONFIG = "watch.config";
  public static final String PROJECT = "project";
  public static final String KEY_NOTIFY = "notify";

  private final Account.Id accountId;
  private final Config cfg;
  private final ValidationError.Sink validationErrorSink;

  private ImmutableMap<ProjectWatchKey, ImmutableSet<NotifyType>> projectWatches;

  ProjectWatches(Account.Id accountId, Config cfg, ValidationError.Sink validationErrorSink) {
    this.accountId = requireNonNull(accountId, "accountId");
    this.cfg = requireNonNull(cfg, "cfg");
    this.validationErrorSink = requireNonNull(validationErrorSink, "validationErrorSink");
  }

  public ImmutableMap<ProjectWatchKey, ImmutableSet<NotifyType>> getProjectWatches() {
    if (projectWatches == null) {
      parse();
    }
    return projectWatches;
  }

  public void parse() {
    projectWatches = parse(accountId, cfg, validationErrorSink);
  }

  /**
   * Parses project watches from the given config file and returns them as a map.
   *
   * <p>A project watch is defined on a project and has a filter to match changes for which the
   * project watch should be applied. The project and the filter form the map key. The map value is
   * a set of notify types that decide for which events email notifications should be sent.
   *
   * <p>A project watch on the {@code All-Projects} project applies for all projects unless the
   * project has a matching project watch.
   *
   * <p>A project watch can have an empty set of notify types. An empty set of notify types means
   * that no notification for matching changes should be set. This is different from no project
   * watch as it overwrites matching project watches from the {@code All-Projects} project.
   *
   * <p>Since we must be able to differentiate a project watch with an empty set of notify types
   * from no project watch we can't use a {@link Multimap} as return type.
   *
   * @param accountId the ID of the account for which the project watches should be parsed
   * @param cfg the config file from which the project watches should be parsed
   * @param validationErrorSink validation error sink
   * @return the parsed project watches
   */
  @VisibleForTesting
  public static ImmutableMap<ProjectWatchKey, ImmutableSet<NotifyType>> parse(
      Account.Id accountId, Config cfg, ValidationError.Sink validationErrorSink) {
    Map<ProjectWatchKey, Set<NotifyType>> projectWatches = new HashMap<>();
    for (String projectName : cfg.getSubsections(PROJECT)) {
      String[] notifyValues = cfg.getStringList(PROJECT, projectName, KEY_NOTIFY);
      for (String nv : notifyValues) {
        if (Strings.isNullOrEmpty(nv)) {
          continue;
        }

        NotifyValue notifyValue =
            NotifyValue.parse(accountId, projectName, nv, validationErrorSink);
        if (notifyValue == null) {
          continue;
        }

        ProjectWatchKey key =
            ProjectWatchKey.create(Project.nameKey(projectName), notifyValue.filter());
        if (!projectWatches.containsKey(key)) {
          projectWatches.put(key, EnumSet.noneOf(NotifyType.class));
        }
        projectWatches.get(key).addAll(notifyValue.notifyTypes());
      }
    }
    return immutableCopyOf(projectWatches);
  }

  public Config save(Map<ProjectWatchKey, Set<NotifyType>> projectWatches) {
    this.projectWatches = immutableCopyOf(projectWatches);

    for (String projectName : cfg.getSubsections(PROJECT)) {
      cfg.unsetSection(PROJECT, projectName);
    }

    ListMultimap<String, String> notifyValuesByProject =
        MultimapBuilder.hashKeys().arrayListValues().build();
    for (Map.Entry<ProjectWatchKey, Set<NotifyType>> e : projectWatches.entrySet()) {
      NotifyValue notifyValue = NotifyValue.create(e.getKey().filter(), e.getValue());
      notifyValuesByProject.put(e.getKey().project().get(), notifyValue.toString());
    }

    for (Map.Entry<String, Collection<String>> e : notifyValuesByProject.asMap().entrySet()) {
      cfg.setStringList(PROJECT, e.getKey(), KEY_NOTIFY, new ArrayList<>(e.getValue()));
    }

    return cfg;
  }

  private static ImmutableMap<ProjectWatchKey, ImmutableSet<NotifyType>> immutableCopyOf(
      Map<ProjectWatchKey, Set<NotifyType>> projectWatches) {
    ImmutableMap.Builder<ProjectWatchKey, ImmutableSet<NotifyType>> b = ImmutableMap.builder();
    projectWatches.entrySet().stream()
        .forEach(e -> b.put(e.getKey(), ImmutableSet.copyOf(e.getValue())));
    return b.build();
  }

  @AutoValue
  public abstract static class NotifyValue {
    public static NotifyValue parse(
        Account.Id accountId,
        String project,
        String notifyValue,
        ValidationError.Sink validationErrorSink) {
      notifyValue = notifyValue.trim();
      int i = notifyValue.lastIndexOf('[');
      if (i < 0 || notifyValue.charAt(notifyValue.length() - 1) != ']') {
        validationErrorSink.error(
            new ValidationError(
                WATCH_CONFIG,
                String.format(
                    "Invalid project watch of account %d for project %s: %s",
                    accountId.get(), project, notifyValue)));
        return null;
      }
      String filter = notifyValue.substring(0, i).trim();
      if (filter.isEmpty() || FILTER_ALL.equals(filter)) {
        filter = null;
      }

      Set<NotifyType> notifyTypes = EnumSet.noneOf(NotifyType.class);
      if (i + 1 < notifyValue.length() - 2) {
        for (String nt :
            Splitter.on(',')
                .trimResults()
                .splitToList(notifyValue.substring(i + 1, notifyValue.length() - 1))) {
          NotifyType notifyType = Enums.getIfPresent(NotifyType.class, nt).orNull();
          if (notifyType == null) {
            validationErrorSink.error(
                new ValidationError(
                    WATCH_CONFIG,
                    String.format(
                        "Invalid notify type %s in project watch "
                            + "of account %d for project %s: %s",
                        nt, accountId.get(), project, notifyValue)));
            continue;
          }
          notifyTypes.add(notifyType);
        }
      }
      return create(filter, notifyTypes);
    }

    public static NotifyValue create(@Nullable String filter, Collection<NotifyType> notifyTypes) {
      return new AutoValue_ProjectWatches_NotifyValue(
          Strings.emptyToNull(filter), Sets.immutableEnumSet(notifyTypes));
    }

    public abstract @Nullable String filter();

    public abstract ImmutableSet<NotifyType> notifyTypes();

    @Override
    public final String toString() {
      List<NotifyType> notifyTypes = new ArrayList<>(notifyTypes());
      StringBuilder notifyValue = new StringBuilder();
      notifyValue.append(firstNonNull(filter(), FILTER_ALL)).append(" [");
      Joiner.on(", ").appendTo(notifyValue, notifyTypes);
      notifyValue.append("]");
      return notifyValue.toString();
    }
  }
}
