// Copyright (C) 2015 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.verifystatus;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.verifystatus.common.VerificationInfo;
import com.googlesource.gerrit.plugins.verifystatus.common.VerifyInput;
import com.googlesource.gerrit.plugins.verifystatus.server.CiDb;
import com.googlesource.gerrit.plugins.verifystatus.server.DbChangeId;
import com.googlesource.gerrit.plugins.verifystatus.server.DbLabelId;
import com.googlesource.gerrit.plugins.verifystatus.server.DbPatchSetId;
import com.googlesource.gerrit.plugins.verifystatus.server.PatchSetVerification;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
@RequiresCapability(value = SaveReportCapability.ID, fallBackToAdmin = false)
public class PostVerification implements RestModifyView<RevisionResource, VerifyInput> {
  private static final Logger log = LoggerFactory.getLogger(PostVerification.class);
  private final SchemaFactory<CiDb> schemaFactory;

  @Inject
  PostVerification(SchemaFactory<CiDb> schemaFactory) {
    this.schemaFactory = schemaFactory;
  }

  @Override
  public Response<?> apply(RevisionResource revision, VerifyInput input)
      throws BadRequestException, OrmException {
    if (input.verifications == null) {
      throw new BadRequestException("Missing verifications field");
    }

    try (CiDb db = schemaFactory.open()) {
      // Only needed for Google Megastore (that we don't use yet)
      db.patchSetVerifications().beginTransaction(null);
      boolean dirty = false;
      try {
        dirty |= updateLabels(revision, db, input.verifications);
        if (dirty) {
          db.commit();
        }
      } finally {
        db.rollback();
      }
    }
    return Response.none();
  }

  private boolean updateLabels(
      RevisionResource resource, CiDb db, Map<String, VerificationInfo> jobs)
      throws OrmException, BadRequestException {
    Preconditions.checkNotNull(jobs);

    List<PatchSetVerification> ups = Lists.newArrayList();
    Map<String, PatchSetVerification> current = scanLabels(resource, db);

    Timestamp ts = Timestamp.from(TimeUtil.now());
    for (Map.Entry<String, VerificationInfo> ent : jobs.entrySet()) {
      String name = ent.getKey();
      if (name == null) {
        throw new BadRequestException("Missing name field");
      }
      PatchSetVerification c = current.remove(name);
      Short value = ent.getValue().value;
      if (value == null) {
        throw new BadRequestException("Missing value field");
      }
      if (c != null) {
        // update a result
        c.setGranted(ts);
        c.setValue(value);
        if (Boolean.TRUE.equals(ent.getValue().abstain)) {
          c.setAbstain(true);
        }
        if (Boolean.TRUE.equals(ent.getValue().rerun)) {
          c.setRerun(true);
        }
        String url = ent.getValue().url;
        if (url != null) {
          c.setUrl(url);
        }
        String job_name = c.getName();
        if (job_name != null) {
          c.setName(job_name);
        }
        String reporter = ent.getValue().reporter;
        if (reporter != null) {
          c.setReporter(reporter);
        }
        String comment = ent.getValue().comment;
        if (comment != null) {
          c.setComment(comment);
        }
        String category = ent.getValue().category;
        if (category != null) {
          c.setCategory(category);
        }
        String duration = ent.getValue().duration;
        if (duration != null) {
          c.setDuration(duration);
        }
        log.info("Updating job " + c.getJob() + " for change " + c.getPatchSetId());
        ups.add(c);
      } else {
        // add new result
        String job_id = UUID.randomUUID().toString();
        DbPatchSetId patchSetId =
            new DbPatchSetId(
                new DbChangeId(resource.getPatchSet().id().changeId().get()),
                resource.getPatchSet().id().get());
        DbLabelId labelId = new DbLabelId(job_id);
        c = new PatchSetVerification(new PatchSetVerification.Key(patchSetId, labelId), value, ts);
        c.setAbstain(ent.getValue().abstain);
        c.setRerun(ent.getValue().rerun);
        c.setUrl(ent.getValue().url);
        c.setName(name);
        c.setReporter(ent.getValue().reporter);
        c.setComment(ent.getValue().comment);
        c.setCategory(ent.getValue().category);
        c.setDuration(ent.getValue().duration);
        log.info("Adding job " + c.getJob() + " for change " + c.getPatchSetId());
        ups.add(c);
      }
    }

    db.patchSetVerifications().upsert(ups);
    return !ups.isEmpty();
  }

  private Map<String, PatchSetVerification> scanLabels(RevisionResource rsrc, CiDb db)
      throws OrmException {
    Map<String, PatchSetVerification> current = Maps.newHashMap();
    DbPatchSetId id =
        new DbPatchSetId(
            new DbChangeId(rsrc.getPatchSet().id().changeId().get()),
            rsrc.getPatchSet().id().get());
    for (PatchSetVerification v : db.patchSetVerifications().byPatchSet(id)) {
      current.put(v.getJobId().get(), v);
    }
    return current;
  }
}
