// 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.common.Die;
import com.google.gerrit.util.cli.CmdLineParser;
import com.google.gerrit.util.cli.OptionHandlers;

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

import java.io.StringWriter;

/** 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 CmdLineParser clp = new CmdLineParser(OptionHandlers.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;
    }
  }

  /** 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;
}
