// Copyright (C) 2016 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.hooks;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.flogger.FluentLogger;
import com.google.common.io.ByteStreams;
import com.google.gerrit.metrics.Timer1;
import com.google.gerrit.reviewdb.client.Project;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import org.eclipse.jgit.lib.Repository;

class HookTask {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  private final Path sitePath;
  private final String projectName;
  private final Path hook;
  private final HookArgs args;
  private StringWriter output;
  private Process ps;

  public static class Async extends HookTask implements Runnable {
    Async(String projectName, Path hook, HookArgs args) {
      super(projectName, hook, args);
    }

    @Override
    public void run() {
      super.runHook();
    }
  }

  public static class Sync extends HookTask implements Callable<HookResult> {
    Sync(String projectName, Path hook, HookArgs args) {
      super(projectName, hook, args);
    }

    @Override
    public HookResult call() throws Exception {
      return super.runHook();
    }
  }

  HookTask(String projectName, Path hook, HookArgs args) {
    this.projectName = projectName;
    this.hook = hook;
    this.args = args;
    this.sitePath = args.sitePaths.site_path;
  }

  public void cancel() {
    ps.destroy();
  }

  protected String getName() {
    return hook.getFileName().toString();
  }

  public String getOutput() {
    return output != null ? output.toString() : null;
  }

  public HookResult runHook() {
    HookResult result = null;
    String name = getName();
    try (Timer1.Context<String> timer = args.metrics.start(name)) {
      args.metrics.count(name);
      List<String> argv = new ArrayList<>(1 + args.get().size());
      argv.add(hook.toAbsolutePath().toString());
      argv.addAll(args.get());

      ProcessBuilder pb = new ProcessBuilder(argv);
      pb.redirectErrorStream(true);

      Map<String, String> env = pb.environment();
      env.put("GERRIT_SITE", sitePath.toAbsolutePath().toString());

      if (projectName != null) {
        try (Repository git = args.gitManager.openRepository(Project.nameKey(projectName))) {
          pb.directory(git.getDirectory());
          env.put("GIT_DIR", git.getDirectory().getAbsolutePath());
        }
      }

      ps = pb.start();
      ps.getOutputStream().close();
      String out = new String(ByteStreams.toByteArray(ps.getInputStream()), UTF_8);
      ps.waitFor();
      result = new HookResult(ps.exitValue(), out);
    } catch (InterruptedException iex) {
      // InterruptedException - timeout or cancel
      args.metrics.timeout(name);
      logger.atSevere().log("hook[%s] timed out: %s", name, iex.getMessage());
    } catch (Throwable err) {
      args.metrics.error(name);
      logger.atSevere().withCause(err).log("Error running hook %s", hook.toAbsolutePath());
    }

    if (result != null) {
      int exitValue = result.getExitValue();
      if (exitValue != 0) {
        logger.atSevere().log("hook[%s] exited with error status: %d", name, exitValue);
      }

      if (logger.atFine().isEnabled()) {
        try (BufferedReader br = new BufferedReader(new StringReader(result.getOutput()))) {
          br.lines()
              .filter(s -> !s.isEmpty())
              .forEach(line -> logger.atFine().log("hook[%s] output: %s", name, line));
        } catch (IOException iox) {
          logger.atSevere().withCause(iox).log("Error writing hook [%s] output", name);
        }
      }
    }

    return result;
  }

  @Override
  public String toString() {
    return "hook " + hook.getFileName();
  }
}
