// Copyright (C) 2017 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.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.inject.Inject;
import com.googlesource.gerrit.plugins.its.base.its.ItsFacade;
import com.googlesource.gerrit.plugins.its.base.workflow.Property;
import java.util.Set;
import org.apache.commons.lang.StringEscapeUtils;

/** Extractor to translate the various {@code *Attribute}s to {@link Property Properties}. */
public class PropertyAttributeExtractor {
  private Property.Factory propertyFactory;
  private ItsFacade its;

  @Inject
  PropertyAttributeExtractor(ItsFacade its, Property.Factory propertyFactory) {
    this.its = its;
    this.propertyFactory = propertyFactory;
  }

  public Set<Property> extractFrom(AccountAttribute accountAttribute, String prefix) {
    Set<Property> properties = Sets.newHashSet();
    if (accountAttribute != null) {
      // deprecated, to be removed soon. migrate to ones without dash.
      properties.add(propertyFactory.create(prefix + "-email", accountAttribute.email));
      properties.add(propertyFactory.create(prefix + "-username", accountAttribute.username));
      properties.add(propertyFactory.create(prefix + "-name", accountAttribute.name));

      // New style configs for vm and soy
      properties.add(propertyFactory.create(prefix + "Email", accountAttribute.email));
      properties.add(propertyFactory.create(prefix + "Username", accountAttribute.username));
      properties.add(propertyFactory.create(prefix + "Name", accountAttribute.name));
    }
    return properties;
  }

  public Set<Property> extractFrom(ChangeAttribute changeAttribute) {
    Set<Property> properties = Sets.newHashSet();
    properties.add(propertyFactory.create("project", changeAttribute.project));
    properties.add(propertyFactory.create("branch", changeAttribute.branch));
    properties.add(propertyFactory.create("topic", changeAttribute.topic));
    properties.add(propertyFactory.create("subject", changeAttribute.subject));
    properties.add(propertyFactory.create("escapedSubject", StringEscapeUtils.escapeJava(changeAttribute.subject)));

    // deprecated, to be removed soon. migrate to ones without dash.
    properties.add(propertyFactory.create("commit-message", changeAttribute.commitMessage));
    properties.add(propertyFactory.create("change-id", changeAttribute.id));
    properties.add(propertyFactory.create("change-number", String.valueOf(changeAttribute.number)));
    properties.add(propertyFactory.create("change-url", changeAttribute.url));

    // New style configs for vm and soy
    properties.add(propertyFactory.create("commitMessage", changeAttribute.commitMessage));
    properties.add(propertyFactory.create("changeId", changeAttribute.id));
    properties.add(propertyFactory.create("changeNumber", String.valueOf(changeAttribute.number)));
    properties.add(propertyFactory.create("changeUrl", changeAttribute.url));

    // Soy specfic config though will work with Velocity too
    properties.add(
        propertyFactory.create(
            "formatChangeUrl", its.createLinkForWebui(changeAttribute.url, changeAttribute.url)));

    String status = null;
    if (changeAttribute.status != null) {
      status = changeAttribute.status.toString();
    }
    properties.add(propertyFactory.create("status", status));
    properties.addAll(extractFrom(changeAttribute.owner, "owner"));
    return properties;
  }

  public Set<Property> extractFrom(PatchSetAttribute patchSetAttribute) {
    Set<Property> properties = Sets.newHashSet();
    properties.add(propertyFactory.create("revision", patchSetAttribute.revision));
    // deprecated, to be removed soon. migrate to ones without dash.
    properties.add(
        propertyFactory.create("patch-set-number", String.valueOf(patchSetAttribute.number)));

    // New style configs for vm and soy
    properties.add(
        propertyFactory.create("patchSetNumber", String.valueOf(patchSetAttribute.number)));

    properties.add(propertyFactory.create("ref", patchSetAttribute.ref));

    // deprecated, to be removed soon. migrate to ones without dash.
    properties.add(propertyFactory.create("created-on", patchSetAttribute.createdOn.toString()));

    // New style configs for vm and soy
    properties.add(propertyFactory.create("createdOn", patchSetAttribute.createdOn.toString()));

    properties.add(propertyFactory.create("parents", patchSetAttribute.parents.toString()));
    properties.add(
        propertyFactory.create("deletions", Integer.toString(patchSetAttribute.sizeDeletions)));
    properties.add(
        propertyFactory.create("insertions", Integer.toString(patchSetAttribute.sizeInsertions)));
    properties.addAll(extractFrom(patchSetAttribute.uploader, "uploader"));
    properties.addAll(extractFrom(patchSetAttribute.author, "author"));
    return properties;
  }

  public Set<Property> extractFrom(RefUpdateAttribute refUpdateAttribute) {
    Set<Property> properties = Sets.newHashSet();
    properties.add(propertyFactory.create("revision", refUpdateAttribute.newRev));

    // deprecated, to be removed soon. migrate to ones without dash.
    properties.add(propertyFactory.create("revision-old", refUpdateAttribute.oldRev));

    // New style configs for vm and soy
    properties.add(propertyFactory.create("revisionOld", refUpdateAttribute.oldRev));
    properties.add(propertyFactory.create("project", refUpdateAttribute.project));
    properties.add(propertyFactory.create("ref", refUpdateAttribute.refName));
    return properties;
  }

  public Set<Property> extractFrom(ApprovalAttribute approvalAttribute) {
    Set<Property> properties = Sets.newHashSet();
    // deprecated, to be removed soon. migrate to ones without dash.
    properties.add(
        propertyFactory.create("approval-" + approvalAttribute.type, approvalAttribute.value));

    // New style configs for vm and soy
    properties.add(
        propertyFactory.create(
            "approval" + approvalAttribute.type.replace("-", ""), approvalAttribute.value));
    return properties;
  }
}
