// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

#pragma once

#include <sasl/sasl.h>

#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <thrift/transport/TTransportException.h>
#include <thrift/transport/TVirtualTransport.h>

#include "kudu/rpc/sasl_common.h"
#include "kudu/rpc/sasl_helper.h"
#include "kudu/util/faststring.h"
#include "kudu/util/slice.h"
#include "kudu/util/status.h"

namespace apache {
namespace thrift {
namespace transport {
class TTransport;
} // namespace transport
} // namespace thrift
} // namespace apache

namespace kudu {
namespace thrift {

// An exception representing a SASL or Kerberos failure.
class SaslException : public apache::thrift::transport::TTransportException {
 public:
  explicit SaslException(Status status)
    : TTransportException(status.ToString()),
      status_(std::move(status)) {
  }

  const Status& status() const {
    return status_;
  }

 private:
  Status status_;
};

// An enum describing the possible states of the SASL negotiation protocol.
enum NegotiationStatus {
  TSASL_INVALID = -1,
  TSASL_START = 1,
  TSASL_OK = 2,
  TSASL_BAD = 3,
  TSASL_ERROR = 4,
  TSASL_COMPLETE = 5
};

// A Thrift transport which uses SASL GSSAPI to authenticate as a client to a
// remote server.
//
// SaslClientTransport internally holds buffers, so it does not need the
// underlying transport to be buffered.
class SaslClientTransport
    : public apache::thrift::transport::TVirtualTransport<SaslClientTransport> {
 public:
  SaslClientTransport(std::string service_principal,
                      const std::string& server_fqdn,
                      std::shared_ptr<TTransport> transport,
                      size_t max_recv_buf_size);

  ~SaslClientTransport() override = default;

  bool isOpen() override;

  bool peek() override;

  void open() override;

  void close() override;

  uint32_t read(uint8_t* buf, uint32_t len);

  void write(const uint8_t* buf, uint32_t len);

  void flush() override;

  int GetOptionCb(const char* plugin_name, const char* option,
                  const char** result, unsigned* len);

 private:

  // Runs SASL negotiation with the remote server.
  void Negotiate();

  // Sends a SASL negotiation message to the underlying transport.
  //
  // Send a SASL negotiation message using the Thrift framing protocol:
  //
  // - 1 byte of status
  // - 4 bytes of remaining length
  // - var-len payload
  void SendSaslMessage(NegotiationStatus status, Slice payload);

  // Receives a SASL negotiation message from the underlying transport.
  //
  // The returned negotiation status will be of type OK or COMPLETE, all
  // other statuses result in an exception.
  NegotiationStatus ReceiveSaslMessage(faststring* payload);

  // Initializes SASL state.
  void SetupSaslContext();

  // Sends the initial SASL connection message.
  void SendSaslStart();

  // Reads a frame from the underlying transport, storing the payload into
  // read_slice_. If the connection is using SASL auth-conf or auth-int
  // protection the data is automatically decoded.
  void ReadFrame();

  // Resets the read buffer to empty, and deallocates its internal buffer.
  void ResetReadBuf();

  // Resets the write buffer to the size of a frame header, and deallocates its
  // internal buffer.
  void ResetWriteBuf();

  // The underlying transport. Typically a TCP socket.
  std::shared_ptr<TTransport> transport_;

  // SASL state.
  rpc::SaslHelper sasl_helper_;
  std::unique_ptr<sasl_conn_t, rpc::SaslDeleter> sasl_conn_;
  std::vector<sasl_callback_t> sasl_callbacks_;

  // Whether the connection is using auth-int or auth-conf protection.
  bool needs_wrap_;

  // The negotiated SASL maximum buffer sizes. These correspond to the maximum
  // sized frames that can be received or sent.
  //
  // Note: the Java implementation of the Thrift SASL transport does not respect
  // the negotiated maximum buffer size (THRIFT-4483) and never splits a message
  // into multiple frames, so we end up having to set the recv buf size to match
  // the largest serialized Thrift message we want to be able to receive.
  size_t max_recv_buf_size_;
  size_t max_send_buf_size_;

  // The read buffer and slice. The slice points to the remaining frame data
  // which hasn't been read yet.
  faststring read_buf_;
  Slice read_slice_;

  // The write buffer.
  faststring write_buf_;

  // The principal of the service being connected to.
  std::string service_principal_;
};

} // namespace thrift
} // namespace kudu
