// 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.common.collect.Sets;
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.Event;
import com.google.gerrit.server.events.PatchSetCreatedEvent;
import com.google.gerrit.server.events.PatchSetEvent;
import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.inject.Inject;

import com.googlesource.gerrit.plugins.its.base.workflow.Property;

import org.eclipse.jgit.lib.ObjectId;

import java.util.Collections;
import java.util.Map;
import java.util.Set;

/**
 * Extractor to translate an {@link ChangeEvent} to
 * {@link Property Properties}.
 */
public class PropertyExtractor {
  private IssueExtractor issueExtractor;
  private Property.Factory propertyFactory;
  private PropertyAttributeExtractor propertyAttributeExtractor;
  private final String pluginName;

  @Inject
  PropertyExtractor(IssueExtractor issueExtractor,
      Property.Factory propertyFactory,
      PropertyAttributeExtractor propertyAttributeExtractor,
      @PluginName String pluginName) {
    this.issueExtractor = issueExtractor;
    this.propertyFactory = propertyFactory;
    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>> extractFrom(PatchSetEvent event,
      Set<Property> common) {
    common.add(propertyFactory.create("event-type", event.type));
    ChangeAttribute change = event.change.get();
    PatchSetAttribute patchSet = event.patchSet.get();
    common.addAll(propertyAttributeExtractor.extractFrom(change));
    common.addAll(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,
      Set<Property> common) {
    common.addAll(propertyAttributeExtractor.extractFrom(event.abandoner.get(), "abandoner"));
    common.add(propertyFactory.create("reason", event.reason));
    return extractFrom((PatchSetEvent) event, common);
  }

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

  private Map<String,Set<String>> extractFrom(ChangeRestoredEvent event,
      Set<Property> common) {
    common.addAll(propertyAttributeExtractor.extractFrom(event.restorer.get(), "restorer"));
    common.add(propertyFactory.create("reason", event.reason));
    return extractFrom((PatchSetEvent) event, common);
  }

  private Map<String,Set<String>> extractFrom(RefUpdatedEvent event,
      Set<Property> common) {
    common.add(propertyFactory.create("event-type", event.type));
    common.addAll(propertyAttributeExtractor.extractFrom(event.submitter.get(), "submitter"));
    common.addAll(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,
      Set<Property> common) {
    common.addAll(propertyAttributeExtractor.extractFrom(event.uploader.get(), "uploader"));
    return extractFrom((PatchSetEvent) event, common);
  }

  private Map<String,Set<String>> extractFrom(CommentAddedEvent event,
      Set<Property> common) {
    common.addAll(propertyAttributeExtractor.extractFrom(event.author.get(), "commenter"));
    if (event.approvals != null) {
      for (ApprovalAttribute approvalAttribute : event.approvals.get()) {
        common.addAll(propertyAttributeExtractor.extractFrom(
            approvalAttribute));
      }
    }
    common.add(propertyFactory.create("comment", event.comment));
    return extractFrom((PatchSetEvent) event, common);
  }

  /**
   * A set of property sets extracted from an event.
   *
   * As events may relate to more that a single issue, and properties sets are
   * should be tied to a single issue, returning {@code Set<Property>} is not
   * sufficient, and we need to return {@code Set<Set<Property>>}. 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 sets from.
   * @return sets of property sets extracted from the event.
   */
  public Set<Set<Property>> extractFrom(Event event) {
    Map<String,Set<String>> associations = null;
    Set<Set<Property>> ret = Sets.newHashSet();

    Set<Property> common = Sets.newHashSet();
    common.add(propertyFactory.create("event", event.getClass().getName()));

    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);
    }

    if (associations != null) {
      for (String issue : associations.keySet()) {
        Set<Property> properties = Sets.newHashSet();
        Property property = propertyFactory.create("issue", issue);
        properties.add(property);
        property = propertyFactory.create("its-name", pluginName);
        properties.add(property);
        for (String occurrence: associations.get(issue)) {
          property = propertyFactory.create("association", occurrence);
          properties.add(property);
        }
        properties.addAll(common);
        ret.add(properties);
      }
    }
    return ret;
  }
}
