// Copyright (C) 2010 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.server.CurrentUser;

import org.apache.sshd.common.Session.AttributeKey;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;

/** Global data related to an active SSH connection. */
public class SshSession {
  /** ServerSession attribute key for this object instance. */
  public static final AttributeKey<SshSession> KEY =
      new AttributeKey<SshSession>();

  private final int sessionId;
  private final SocketAddress remoteAddress;
  private final String remoteAsString;

  private volatile CurrentUser identity;
  private volatile String username;
  private volatile String authError;

  SshSession(final int sessionId, SocketAddress peer) {
    this.sessionId = sessionId;
    this.remoteAddress = peer;
    this.remoteAsString = format(remoteAddress);
  }

  SshSession(SshSession parent, SocketAddress peer, CurrentUser user) {
    this.sessionId = parent.sessionId;
    this.remoteAddress = peer;
    if (parent.remoteAddress == peer) {
      this.remoteAsString = parent.remoteAsString;
    } else {
      this.remoteAsString = format(peer) + "/" + parent.remoteAsString;
    }
    this.identity = user;
  }

  /** Unique session number, assigned during connect. */
  public int getSessionId() {
    return sessionId;
  }

  /** Identity of the authenticated user account on the socket. */
  public CurrentUser getCurrentUser() {
    return identity;
  }

  String getUsername() {
    return username;
  }

  String getAuthenticationError() {
    return authError;
  }

  void authenticationSuccess(String user, CurrentUser id) {
    username = user;
    identity = id;
    authError = null;
  }

  void authenticationError(String user, String error) {
    username = user;
    identity = null;
    authError = error;
  }

  /** @return {@code true} if the authentication did not succeed. */
  boolean isAuthenticationError() {
    return authError != null;
  }

  SocketAddress getRemoteAddress() {
    return remoteAddress;
  }

  String getRemoteAddressAsString() {
    return remoteAsString;
  }

  private static String format(final SocketAddress remote) {
    if (remote instanceof InetSocketAddress) {
      final InetSocketAddress sa = (InetSocketAddress) remote;

      final InetAddress in = sa.getAddress();
      if (in != null) {
        return in.getHostAddress();
      }

      final String hostName = sa.getHostName();
      if (hostName != null) {
        return hostName;
      }
    }
    return remote.toString();
  }
}
