// 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 static org.easymock.EasyMock.expect;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.data.AccountAttribute;
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.ChangeMergedEvent;
import com.google.gerrit.server.events.ChangeRestoredEvent;
import com.google.gerrit.server.events.CommentAddedEvent;
import com.google.gerrit.server.events.DraftPublishedEvent;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.PatchSetCreatedEvent;
import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.inject.Guice;
import com.google.inject.Injector;

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

import java.util.HashMap;
import java.util.Set;

public class PropertyExtractorTest extends LoggingMockingTestCase {
  private Injector injector;

  private IssueExtractor issueExtractor;
  private Property.Factory propertyFactory;
  private PropertyAttributeExtractor propertyAttributeExtractor;

  public void testDummyChangeEvent() {
    PropertyExtractor propertyExtractor = injector.getInstance(
        PropertyExtractor.class);

    Property property1 = createMock(Property.class);
    expect(propertyFactory.create("event", "com.googlesource.gerrit.plugins." +
        "its.base.util.PropertyExtractorTest$DummyEvent"))
        .andReturn(property1);

    replayMocks();

    Set<Set<Property>> actual = propertyExtractor.extractFrom(
        new DummyEvent());

    Set<Set<Property>> expected = Sets.newHashSet();
    assertEquals("Properties do not match", expected, actual);
  }

  public void testChangeAbandonedEvent() {
    ChangeAbandonedEvent event = new ChangeAbandonedEvent();

    ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
    event.change = changeAttribute;
    Property propertyChange = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(changeAttribute))
        .andReturn(Sets.newHashSet(propertyChange));

    AccountAttribute accountAttribute = createMock(AccountAttribute.class);
    event.abandoner= accountAttribute;
    Property propertySubmitter = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
        "abandoner")).andReturn(Sets.newHashSet(propertySubmitter));

    PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
    event.patchSet = patchSetAttribute;
    Property propertyPatchSet = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(patchSetAttribute))
        .andReturn(Sets.newHashSet(propertyPatchSet));

    event.reason = "testReason";
    Property propertyReason = createMock(Property.class);
    expect(propertyFactory.create("reason", "testReason"))
        .andReturn(propertyReason);

    changeAttribute.project = "testProject";
    changeAttribute.number = "176";
    patchSetAttribute.revision = "testRevision";
    patchSetAttribute.number = "3";

    Set<Property> common = Sets.newHashSet();
    common.add(propertyChange);
    common.add(propertySubmitter);
    common.add(propertyPatchSet);
    common.add(propertyReason);

    eventHelper(event, "ChangeAbandonedEvent", "change-abandoned", common,
        true);
  }

  public void testChangeMergedEvent() {
    ChangeMergedEvent event = new ChangeMergedEvent();

    ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
    event.change = changeAttribute;
    Property propertyChange = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(changeAttribute))
        .andReturn(Sets.newHashSet(propertyChange));

    AccountAttribute accountAttribute = createMock(AccountAttribute.class);
    event.submitter = accountAttribute;
    Property propertySubmitter = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
        "submitter")).andReturn(Sets.newHashSet(propertySubmitter));

    PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
    event.patchSet = patchSetAttribute;
    Property propertyPatchSet = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(patchSetAttribute))
        .andReturn(Sets.newHashSet(propertyPatchSet));

    changeAttribute.project = "testProject";
    changeAttribute.number = "176";
    patchSetAttribute.revision = "testRevision";
    patchSetAttribute.number = "3";

    Set<Property> common = Sets.newHashSet();
    common.add(propertyChange);
    common.add(propertySubmitter);
    common.add(propertyPatchSet);

    eventHelper(event, "ChangeMergedEvent", "change-merged", common, true);
  }

  public void testChangeRestoredEvent() {
    ChangeRestoredEvent event = new ChangeRestoredEvent();

    ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
    event.change = changeAttribute;
    Property propertyChange = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(changeAttribute))
        .andReturn(Sets.newHashSet(propertyChange));

    AccountAttribute accountAttribute = createMock(AccountAttribute.class);
    event.restorer = accountAttribute;
    Property propertySubmitter = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
        "restorer")).andReturn(Sets.newHashSet(propertySubmitter));

    PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
    event.patchSet = patchSetAttribute;
    Property propertyPatchSet = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(patchSetAttribute))
        .andReturn(Sets.newHashSet(propertyPatchSet));

    event.reason = "testReason";
    Property propertyReason = createMock(Property.class);
    expect(propertyFactory.create("reason", "testReason"))
        .andReturn(propertyReason);

    changeAttribute.project = "testProject";
    changeAttribute.number = "176";
    patchSetAttribute.revision = "testRevision";
    patchSetAttribute.number = "3";

    Set<Property> common = Sets.newHashSet();
    common.add(propertyChange);
    common.add(propertySubmitter);
    common.add(propertyPatchSet);
    common.add(propertyReason);

    eventHelper(event, "ChangeRestoredEvent", "change-restored", common, true);
  }

  public void testCommentAddedEventWOApprovals() {
    CommentAddedEvent event = new CommentAddedEvent();

    ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
    event.change = changeAttribute;
    Property propertyChange = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(changeAttribute))
        .andReturn(Sets.newHashSet(propertyChange));

    AccountAttribute accountAttribute = createMock(AccountAttribute.class);
    event.author = accountAttribute;
    Property propertySubmitter = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
        "commenter")).andReturn(Sets.newHashSet(propertySubmitter));

    PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
    event.patchSet = patchSetAttribute;
    Property propertyPatchSet = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(patchSetAttribute))
        .andReturn(Sets.newHashSet(propertyPatchSet));

    event.comment = "testComment";
    Property propertyComment = createMock(Property.class);
    expect(propertyFactory.create("comment", "testComment"))
        .andReturn(propertyComment);

    changeAttribute.project = "testProject";
    changeAttribute.number = "176";
    patchSetAttribute.revision = "testRevision";
    patchSetAttribute.number = "3";

    Set<Property> common = Sets.newHashSet();
    common.add(propertyChange);
    common.add(propertySubmitter);
    common.add(propertyPatchSet);
    common.add(propertyComment);

    eventHelper(event, "CommentAddedEvent", "comment-added", common, true);
  }

  public void testCommentAddedEventWApprovals() {
    CommentAddedEvent event = new CommentAddedEvent();

    ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
    event.change = changeAttribute;
    Property propertyChange = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(changeAttribute))
        .andReturn(Sets.newHashSet(propertyChange));

    AccountAttribute accountAttribute = createMock(AccountAttribute.class);
    event.author = accountAttribute;
    Property propertySubmitter = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
        "commenter")).andReturn(Sets.newHashSet(propertySubmitter));

    PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
    event.patchSet = patchSetAttribute;
    Property propertyPatchSet = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(patchSetAttribute))
        .andReturn(Sets.newHashSet(propertyPatchSet));

    ApprovalAttribute approvalAttribute1 = createMock(ApprovalAttribute.class);
    Property propertyApproval1 = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(approvalAttribute1))
        .andReturn(Sets.newHashSet(propertyApproval1));
    ApprovalAttribute approvalAttribute2 = createMock(ApprovalAttribute.class);
    Property propertyApproval2 = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(approvalAttribute2))
        .andReturn(Sets.newHashSet(propertyApproval2));
    ApprovalAttribute approvalAttributes[] = { approvalAttribute1,
        approvalAttribute2 };
    event.approvals = approvalAttributes;

    event.comment = "testComment";
    Property propertyComment = createMock(Property.class);
    expect(propertyFactory.create("comment", "testComment"))
        .andReturn(propertyComment);

    changeAttribute.project = "testProject";
    changeAttribute.number = "176";
    patchSetAttribute.revision = "testRevision";
    patchSetAttribute.number = "3";

    Set<Property> common = Sets.newHashSet();
    common.add(propertyChange);
    common.add(propertySubmitter);
    common.add(propertyPatchSet);
    common.add(propertyComment);
    common.add(propertyApproval1);
    common.add(propertyApproval2);

    eventHelper(event, "CommentAddedEvent", "comment-added", common, true);
  }

  public void testDraftPublishedEvent() {
    DraftPublishedEvent event = new DraftPublishedEvent();

    ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
    event.change = changeAttribute;
    Property propertyChange = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(changeAttribute))
        .andReturn(Sets.newHashSet(propertyChange));

    AccountAttribute accountAttribute = createMock(AccountAttribute.class);
    event.uploader = accountAttribute;
    Property propertySubmitter = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
        "uploader")).andReturn(Sets.newHashSet(propertySubmitter));

    PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
    event.patchSet = patchSetAttribute;
    Property propertyPatchSet = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(patchSetAttribute))
        .andReturn(Sets.newHashSet(propertyPatchSet));

    changeAttribute.project = "testProject";
    changeAttribute.number = "176";
    patchSetAttribute.revision = "testRevision";
    patchSetAttribute.number = "3";

    Set<Property> common = Sets.newHashSet();
    common.add(propertyChange);
    common.add(propertySubmitter);
    common.add(propertyPatchSet);

    eventHelper(event, "DraftPublishedEvent", "draft-published", common,
        true);
  }

  public void testPatchSetCreatedEvent() {
    PatchSetCreatedEvent event = new PatchSetCreatedEvent();

    ChangeAttribute changeAttribute = createMock(ChangeAttribute.class);
    event.change = changeAttribute;
    Property propertyChange = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(changeAttribute))
        .andReturn(Sets.newHashSet(propertyChange));

    AccountAttribute accountAttribute = createMock(AccountAttribute.class);
    event.uploader = accountAttribute;
    Property propertySubmitter = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
        "uploader")).andReturn(Sets.newHashSet(propertySubmitter));

    PatchSetAttribute patchSetAttribute = createMock(PatchSetAttribute.class);
    event.patchSet = patchSetAttribute;
    Property propertyPatchSet = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(patchSetAttribute))
        .andReturn(Sets.newHashSet(propertyPatchSet));

    changeAttribute.project = "testProject";
    changeAttribute.number = "176";
    patchSetAttribute.revision = "testRevision";
    patchSetAttribute.number = "3";

    Set<Property> common = Sets.newHashSet();
    common.add(propertyChange);
    common.add(propertySubmitter);
    common.add(propertyPatchSet);

    eventHelper(event, "PatchSetCreatedEvent", "patchset-created", common,
        true);
  }

  public void testRefUpdatedEvent() {
    RefUpdatedEvent event = new RefUpdatedEvent();

    AccountAttribute accountAttribute = createMock(AccountAttribute.class);
    event.submitter = accountAttribute;
    Property propertySubmitter = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(accountAttribute,
        "submitter")).andReturn(Sets.newHashSet(propertySubmitter));

    RefUpdateAttribute refUpdateAttribute =
        createMock(RefUpdateAttribute.class);
    event.refUpdate = refUpdateAttribute;
    Property propertyRefUpdated = createMock(Property.class);
    expect(propertyAttributeExtractor.extractFrom(refUpdateAttribute))
        .andReturn(Sets.newHashSet(propertyRefUpdated));

    refUpdateAttribute.project = "testProject";
    refUpdateAttribute.newRev = "testRevision";

    Set<Property> common = Sets.newHashSet();
    common.add(propertySubmitter);
    common.add(propertyRefUpdated);

    eventHelper(event, "RefUpdatedEvent", "ref-updated", common, false);
  }

  private void eventHelper(Event event, String className, String type,
      Set<Property> common, boolean withRevision) {
    PropertyExtractor propertyExtractor = injector.getInstance(
        PropertyExtractor.class);

    Property propertyItsName = createMock(Property.class);
    expect(propertyFactory.create("its-name", "ItsTestName"))
        .andReturn(propertyItsName).anyTimes();

    Property propertyEvent = createMock(Property.class);
    expect(propertyFactory.create("event", "com.google.gerrit.server.events." +
        className)).andReturn(propertyEvent);

    Property propertyEventType = createMock(Property.class);
    expect(propertyFactory.create("event-type", type))
        .andReturn(propertyEventType);

    Property propertyAssociationFooter = createMock(Property.class);
    expect(propertyFactory.create("association", "footer"))
        .andReturn(propertyAssociationFooter);

    Property propertyAssociationAnywhere = createMock(Property.class);
    expect(propertyFactory.create("association", "anywhere"))
        .andReturn(propertyAssociationAnywhere).times(2);

    Property propertyAssociationBody = createMock(Property.class);
    expect(propertyFactory.create("association", "body"))
        .andReturn(propertyAssociationBody);

    Property propertyIssue42 = createMock(Property.class);
    expect(propertyFactory.create("issue", "42"))
        .andReturn(propertyIssue42);

    Property propertyIssue4711 = createMock(Property.class);
    expect(propertyFactory.create("issue", "4711"))
        .andReturn(propertyIssue4711);

    HashMap<String,Set<String>> issueMap = Maps.newHashMap();
    issueMap.put("4711", Sets.newHashSet("body", "anywhere"));
    issueMap.put("42", Sets.newHashSet("footer", "anywhere"));
    if (withRevision) {
      PatchSet.Id patchSetId = new PatchSet.Id(new Change.Id(176), 3);
      expect(issueExtractor.getIssueIds("testProject", "testRevision",
          patchSetId)).andReturn(issueMap);
    } else {
      expect(issueExtractor.getIssueIds("testProject", "testRevision"))
      .andReturn(issueMap);
    }

    replayMocks();

    Set<Set<Property>> actual = propertyExtractor.extractFrom(event);

    Set<Set<Property>> expected = Sets.newHashSet();
    Set<Property> properties = Sets.newHashSet();
    properties.add(propertyItsName);
    properties.add(propertyEvent);
    properties.add(propertyEventType);
    properties.add(propertyAssociationAnywhere);
    properties.add(propertyAssociationFooter);
    properties.add(propertyIssue42);
    properties.addAll(common);
    expected.add(properties);

    properties = Sets.newHashSet();
    properties.add(propertyItsName);
    properties.add(propertyEvent);
    properties.add(propertyEventType);
    properties.add(propertyAssociationAnywhere);
    properties.add(propertyAssociationBody);
    properties.add(propertyIssue4711);
    properties.addAll(common);
    expected.add(properties);
    assertEquals("Properties do not match", expected, actual);
  }

  @Override
  public void setUp() throws Exception {
    super.setUp();
    injector = Guice.createInjector(new TestModule());
  }

  private class TestModule extends FactoryModule {
    @Override
    protected void configure() {
      bind(String.class).annotatedWith(PluginName.class)
          .toInstance("ItsTestName");

      issueExtractor = createMock(IssueExtractor.class);
      bind(IssueExtractor.class).toInstance(issueExtractor);

      propertyAttributeExtractor = createMock(PropertyAttributeExtractor.class);
      bind(PropertyAttributeExtractor.class).toInstance(
          propertyAttributeExtractor);

      propertyFactory = createMock(Property.Factory.class);
      bind(Property.Factory.class).toInstance(propertyFactory);
      //factory(Property.Factory.class);
    }
  }

  private class DummyEvent extends Event {
    public DummyEvent() {
      super(null);
    }
  }
}