// Copyright (C) 2009 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.google.gerrit.pgm.util;


import com.google.gerrit.util.cli.CmdLineParser;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;

import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.Option;

import java.io.StringWriter;
import java.util.Collections;

/** Base class for command line invocations of Gerrit Code Review. */
public abstract class AbstractProgram {
  private final Object sleepLock = new Object();
  private boolean running = true;

  @Option(name = "--show-stack-trace", usage = "display stack trace on failure")
  protected boolean showStackTrace;

  private String getName() {
    String n = getClass().getName();
    int dot = n.lastIndexOf('.');
    if (0 < dot) {
      n = n.substring(dot + 1);
    }
    return n.toLowerCase();
  }

  public final int main(final String[] argv) throws Exception {
    final Injector empty = emptyInjector();
    final CmdLineParser clp = new CmdLineParser(empty, this);
    try {
      clp.parseArgument(argv);
    } catch (CmdLineException err) {
      if (!clp.wasHelpRequestedByOption()) {
        System.err.println("fatal: " + err.getMessage());
        return 1;
      }
    }

    if (clp.wasHelpRequestedByOption()) {
      StringWriter msg = new StringWriter();
      clp.printDetailedUsage(getName(), msg);
      System.err.println(msg.toString());
      return 1;
    }

    try {
      ProxyUtil.configureHttpProxy();
      return run();
    } catch (Die err) {
      if (showStackTrace) {
        err.printStackTrace();
      } else {
        final Throwable cause = err.getCause();
        final String diemsg = err.getMessage();
        if (cause != null && !cause.getMessage().equals(diemsg)) {
          System.err.println("fatal: "
              + cause.getMessage().replaceAll("\n", "\nfatal: "));
        }
        System.err.println("fatal: " + diemsg.replaceAll("\n", "\nfatal: "));
      }
      return 128;
    }
  }

  private static Injector emptyInjector() {
    return Guice.createInjector(Collections.<Module> emptyList());
  }

  /** Create a new exception to indicate we won't continue. */
  protected static Die die(String why) {
    return new Die(why);
  }

  /** Create a new exception to indicate we won't continue. */
  protected static Die die(String why, Throwable cause) {
    return new Die(why, cause);
  }

  /** Method that never returns, e.g. to keep a daemon running. */
  protected int never() {
    synchronized (sleepLock) {
      while (running) {
        try {
          sleepLock.wait(60 * 60 * 1000L);
        } catch (InterruptedException e) {
          continue;
        }
      }
      return 0;
    }
  }

  /**
   * Run this program's logic, returning the command exit status.
   * <p>
   * When this method completes, the JVM is terminated. To keep the JVM running,
   * use {@code return never()}.
   */
  public abstract int run() throws Exception;
}
