// Copyright (C) 2013 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.googlesource.gerrit.plugins.its.base.util;

import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.data.ApprovalAttribute;
import com.google.gerrit.server.data.ChangeAttribute;
import com.google.gerrit.server.data.PatchSetAttribute;
import com.google.gerrit.server.data.RefUpdateAttribute;
import com.google.gerrit.server.events.ChangeAbandonedEvent;
import com.google.gerrit.server.events.ChangeEvent;
import com.google.gerrit.server.events.ChangeMergedEvent;
import com.google.gerrit.server.events.ChangeRestoredEvent;
import com.google.gerrit.server.events.CommentAddedEvent;
import com.google.gerrit.server.events.PatchSetCreatedEvent;
import com.google.gerrit.server.events.PatchSetEvent;
import com.google.gerrit.server.events.RefEvent;
import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.inject.Inject;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.jgit.lib.ObjectId;

/** Extractor to translate an {@link ChangeEvent} to a map of properties}. */
public class PropertyExtractor {
  private IssueExtractor issueExtractor;
  private PropertyAttributeExtractor propertyAttributeExtractor;
  private final String pluginName;

  @Inject
  PropertyExtractor(
      IssueExtractor issueExtractor,
      PropertyAttributeExtractor propertyAttributeExtractor,
      @PluginName String pluginName) {
    this.issueExtractor = issueExtractor;
    this.propertyAttributeExtractor = propertyAttributeExtractor;
    this.pluginName = pluginName;
  }

  /**
   * creates a patch id for change id string and patchset id string.
   *
   * @param changeId String representation of the patch sets {@code Change.Id@}
   * @param patchId String representation of the patch sets {@code Patchset.Id@}
   * @return PatchSet.Id for the specified patch set. If the String to int conversion fails for any
   *     of the parameters, null is returned.
   */
  private PatchSet.Id newPatchSetId(String changeId, String patchId) {
    try {
      return new PatchSet.Id(new Change.Id(Integer.parseInt(changeId)), Integer.parseInt(patchId));
    } catch (NumberFormatException e) {
      return null;
    }
  }

  private Map<String, Set<String>> extractMapFrom(PatchSetEvent event, Map<String, String> common) {
    ChangeAttribute change = event.change.get();
    PatchSetAttribute patchSet = event.patchSet.get();
    common.putAll(propertyAttributeExtractor.extractFrom(change));
    common.putAll(propertyAttributeExtractor.extractFrom(patchSet));
    PatchSet.Id patchSetId =
        newPatchSetId(Integer.toString(change.number), Integer.toString(patchSet.number));
    return issueExtractor.getIssueIds(change.project, patchSet.revision, patchSetId);
  }

  private Map<String, Set<String>> extractFrom(
      ChangeAbandonedEvent event, Map<String, String> common) {
    common.putAll(propertyAttributeExtractor.extractFrom(event.abandoner.get(), "abandoner"));
    common.put("reason", event.reason);
    return extractMapFrom(event, common);
  }

  private Map<String, Set<String>> extractFrom(
      ChangeMergedEvent event, Map<String, String> common) {
    common.putAll(propertyAttributeExtractor.extractFrom(event.submitter.get(), "submitter"));
    return extractMapFrom(event, common);
  }

  private Map<String, Set<String>> extractFrom(
      ChangeRestoredEvent event, Map<String, String> common) {
    common.putAll(propertyAttributeExtractor.extractFrom(event.restorer.get(), "restorer"));
    return extractMapFrom(event, common);
  }

  private Map<String, Set<String>> extractFrom(RefUpdatedEvent event, Map<String, String> common) {
    common.putAll(propertyAttributeExtractor.extractFrom(event.submitter.get(), "submitter"));
    common.putAll(propertyAttributeExtractor.extractFrom(event.refUpdate.get()));
    RefUpdateAttribute refUpdated = event.refUpdate.get();
    if (ObjectId.zeroId().name().equals(refUpdated.newRev)) {
      return Collections.emptyMap();
    }
    return issueExtractor.getIssueIds(event.getProjectNameKey().get(), refUpdated.newRev);
  }

  private Map<String, Set<String>> extractFrom(
      PatchSetCreatedEvent event, Map<String, String> common) {
    common.putAll(propertyAttributeExtractor.extractFrom(event.uploader.get(), "uploader"));
    return extractMapFrom(event, common);
  }

  private Map<String, Set<String>> extractFrom(
      CommentAddedEvent event, Map<String, String> common) {
    common.putAll(propertyAttributeExtractor.extractFrom(event.author.get(), "commenter"));
    common.put("comment", event.comment);
    if (event.approvals != null) {
      for (ApprovalAttribute approvalAttribute : event.approvals.get()) {
        common.putAll(propertyAttributeExtractor.extractFrom(approvalAttribute));
      }
    }
    return extractMapFrom(event, common);
  }

  /**
   * A set of properties extracted from an event.
   *
   * <p>As events may relate to more that a single issue and a group of properties should be tied to
   * a single issue, we need to return {@code Set<Map>} of properties. As properties we understand a
   * map of event attributes. Using this approach, a PatchSetCreatedEvent for a patch set with
   * commit message:
   *
   * <pre>
   *   (bug 4711) Fix treatment of special characters in title
   *
   *   This commit mitigates the effects of bug 42, but does not fix them.
   *
   *   Change-Id: I1234567891123456789212345678931234567894
   * </pre>
   *
   * may return both
   *
   * <pre>
   *   issue: 4711
   *   association: subject
   *   event: patchset-created
   * </pre>
   *
   * and
   *
   * <pre>
   *   issue: 42
   *   association: body
   *   event: patchset-created
   * </pre>
   *
   * Thereby, sites can choose to cause different actions for different issues associated to the
   * same event. So in the above example, a comment "mentioned in change 123" may be added for issue
   * 42, and a comment "fixed by change 123” may be added for issue 4711.
   *
   * @param event The event to extract property maps from.
   * @return set of property maps extracted from the event.
   */
  public Set<Map<String, String>> extractFrom(RefEvent event) {
    Map<String, Set<String>> associations = null;
    Map<String, String> common = new HashMap<>();
    common.put("event", event.getClass().getName());
    common.put("event-type", event.type);
    common.put("project", event.getProjectNameKey().get());
    common.put("ref", event.getRefName());
    common.put("itsName", pluginName);

    if (event instanceof ChangeAbandonedEvent) {
      associations = extractFrom((ChangeAbandonedEvent) event, common);
    } else if (event instanceof ChangeMergedEvent) {
      associations = extractFrom((ChangeMergedEvent) event, common);
    } else if (event instanceof ChangeRestoredEvent) {
      associations = extractFrom((ChangeRestoredEvent) event, common);
    } else if (event instanceof CommentAddedEvent) {
      associations = extractFrom((CommentAddedEvent) event, common);
    } else if (event instanceof PatchSetCreatedEvent) {
      associations = extractFrom((PatchSetCreatedEvent) event, common);
    } else if (event instanceof RefUpdatedEvent) {
      associations = extractFrom((RefUpdatedEvent) event, common);
    }

    Set<Map<String, String>> ret = new HashSet<>();
    if (associations != null) {
      for (Entry<String, Set<String>> assoc : associations.entrySet()) {
        Map<String, String> properties = new HashMap<>();
        properties.put("issue", assoc.getKey());
        properties.put("association", String.join(" ", assoc.getValue()));
        properties.putAll(common);
        ret.add(properties);
      }
    }
    return ret;
  }
}
