// Copyright (C) 2008 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.sshd;

import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.ssh.SshInfo;
import com.google.gerrit.sshd.SshScope.Context;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.apache.sshd.common.Factory;
import org.apache.sshd.server.Command;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
import org.apache.sshd.server.SessionAware;
import org.apache.sshd.server.session.ServerSession;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.util.SystemReader;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * Dummy shell which prints a message and terminates.
 * <p>
 * This implementation is used to ensure clients who try to SSH directly to this
 * server without supplying a command will get a reasonable error message, but
 * cannot continue further.
 */
class NoShell implements Factory<Command> {
  private final Provider<SendMessage> shell;

  @Inject
  NoShell(Provider<SendMessage> shell) {
    this.shell = shell;
  }

  public Command create() {
    return shell.get();
  }

  static class SendMessage implements Command, SessionAware {
    private final Provider<MessageFactory> messageFactory;

    private InputStream in;
    private OutputStream out;
    private OutputStream err;
    private ExitCallback exit;
    private Context context;

    @Inject
    SendMessage(Provider<MessageFactory> messageFactory) {
      this.messageFactory = messageFactory;
    }

    public void setInputStream(final InputStream in) {
      this.in = in;
    }

    public void setOutputStream(final OutputStream out) {
      this.out = out;
    }

    public void setErrorStream(final OutputStream err) {
      this.err = err;
    }

    public void setExitCallback(final ExitCallback callback) {
      this.exit = callback;
    }

    public void setSession(final ServerSession session) {
      this.context = new Context(session.getAttribute(SshSession.KEY), "");
    }

    public void start(final Environment env) throws IOException {
      Context old = SshScope.set(context);
      String message;
      try {
        message = messageFactory.get().getMessage();
      } finally {
        SshScope.set(old);
      }
      err.write(Constants.encode(message.toString()));
      err.flush();

      in.close();
      out.close();
      err.close();
      exit.onExit(127);
    }

    public void destroy() {
    }
  }

  static class MessageFactory {
    private final IdentifiedUser user;
    private final SshInfo sshInfo;
    private final Provider<String> urlProvider;

    @Inject
    MessageFactory(IdentifiedUser user, SshInfo sshInfo,
        @CanonicalWebUrl Provider<String> urlProvider) {
      this.user = user;
      this.sshInfo = sshInfo;
      this.urlProvider = urlProvider;
    }

    String getMessage() {
      StringBuilder msg = new StringBuilder();

      msg.append("\r\n");
      msg.append("  ****    Welcome to Gerrit Code Review    ****\r\n");
      msg.append("\r\n");

      Account account = user.getAccount();
      String name = account.getFullName();
      if (name == null || name.isEmpty()) {
        name = user.getUserName();
      }
      msg.append("  Hi ");
      msg.append(name);
      msg.append(", you have successfully connected over SSH.");
      msg.append("\r\n");
      msg.append("\r\n");

      msg.append("  Unfortunately, interactive shells are disabled.\r\n");
      msg.append("  To clone a hosted Git repository, use:\r\n");
      msg.append("\r\n");

      if (!sshInfo.getHostKeys().isEmpty()) {
        String host = sshInfo.getHostKeys().get(0).getHost();
        if (host.startsWith("*:")) {
          host = getGerritHost() + host.substring(1);
        }

        msg.append("  git clone ssh://");
        msg.append(user.getUserName());
        msg.append("@");
        msg.append(host);
        msg.append("/");
        msg.append("REPOSITORY_NAME.git");
        msg.append("\r\n");
      }

      msg.append("\r\n");
      return msg.toString();
    }

    private String getGerritHost() {
      String url = urlProvider.get();
      if (url != null) {
        try {
          return new URL(url).getHost();
        } catch (MalformedURLException e) {
        }
      }
      return SystemReader.getInstance().getHostname();
    }
  }
}
