/*
 * 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.
 */

#include <thrift/server/TClientInfo.h>

namespace apache { namespace thrift { namespace server {

using namespace apache::thrift;
using namespace apache::thrift::transport;

TClientInfoConnection::TClientInfoConnection() {
  call_[kNameLen - 1] = '\0';    // insure NUL terminator is there
  eraseAddr();
  eraseCall();
}

void TClientInfoConnection::recordAddr(const sockaddr* addr) {
  eraseAddr();
  initTime();
  ncalls_ = 0;
  if (addr != nullptr) {
    if (addr->sa_family == AF_INET) {
      memcpy((void*)&addr_.ipv4, (const void *)addr, sizeof(sockaddr_in));
    }
    else if (addr->sa_family == AF_INET6) {
      memcpy((void*)&addr_.ipv6, (const void *)addr, sizeof(sockaddr_in6));
    }
  }
}

void TClientInfoConnection::eraseAddr() {
  addr_.ipv4.sin_family = AF_UNSPEC;
}

const char* TClientInfoConnection::getAddr(char* buf, int len) const {
  switch (addr_.ipv4.sin_family) {
  case AF_INET:
    return inet_ntop(AF_INET, &addr_.ipv4.sin_addr, buf, len);
  case AF_INET6:
    return inet_ntop(AF_INET6, &addr_.ipv6.sin6_addr, buf, len);
  default:
    return nullptr;
  }
}

void TClientInfoConnection::recordCall(const char* name) {
  strncpy(call_, name, kNameLen - 1);   // NUL terminator set in constructor
  ncalls_++;
}

void TClientInfoConnection::eraseCall() {
  call_[0] = '\0';
}

const char* TClientInfoConnection::getCall() const {
  if (call_[0] == '\0') {
      return nullptr;
  }
  return call_;
}

void TClientInfoConnection::getTime(timespec* time) const {
  *time = time_;
}

uint64_t TClientInfoConnection::getNCalls() const {
  return ncalls_;
}

void TClientInfoConnection::initTime() {
  clock_gettime(CLOCK_REALTIME, &time_);
}


TClientInfoConnection* TClientInfo::getConnection(int fd, bool grow) {
  if (fd < 0 || (!grow && fd >= info_.size())) {
    return nullptr;
  }
  return &info_[fd];
}

size_t TClientInfo::size() const {
    return info_.size();
}

void* TClientInfoServerHandler::createContext(boost::shared_ptr<TProtocol> input,
                                              boost::shared_ptr<TProtocol> output) {
  (void)input;
  (void)output;
  return (void*) new Connect(&clientInfo_);
}

void TClientInfoServerHandler::deleteContext(void* connectionContext,
                                             boost::shared_ptr<TProtocol> input,
                                             boost::shared_ptr<TProtocol> output) {
  Connect* call = static_cast<Connect*>(connectionContext);
  if (call->callInfo_) {
    call->callInfo_->eraseCall();
  }
  delete call;
}

void TClientInfoServerHandler::processContext(void* connectionContext,
                                              shared_ptr<TTransport> transport) {
  Connect* call = static_cast<Connect*>(connectionContext);
  if (call->callInfo_ == nullptr) {
    if (typeid(*(transport.get())) == typeid(TSocket)) {
      TSocket* tsocket = static_cast<TSocket*>(transport.get());
      int fd = tsocket->getSocketFD();
      if (fd < 0) {
        return;
      }
      call->callInfo_ = call->clientInfo_->getConnection(fd, true);
      assert(call->callInfo_ != nullptr);
      socklen_t len;
        call->callInfo_->recordAddr(tsocket->getCachedAddress(&len));
    }
  }
}

void TClientInfoServerHandler::getStatsStrings(vector<string>& result) {
  result.clear();
  timespec now;
  clock_gettime(CLOCK_REALTIME, &now);

  for (int i = 0; i < clientInfo_.size(); ++i) {
    TClientInfoConnection* info = clientInfo_.getConnection(i, false);
    const char* callStr = info->getCall();
    if (callStr == nullptr) {
      continue;
    }

    char addrBuf[INET6_ADDRSTRLEN];
    const char* addrStr = info->getAddr(addrBuf, sizeof addrBuf);
    if (addrStr == nullptr) {
      // cerr << "no addr!" << endl;
      continue;
    }

    timespec start;
    info->getTime(&start);
    double secs = (double)(now.tv_sec - start.tv_sec) + (now.tv_nsec - start.tv_nsec)*0.000000001;

    char buf[256];
    snprintf(buf, sizeof buf, "%d %s %s %.3f %llu", i, addrStr, callStr, secs,
             (uint64_t)info->getNCalls());
               
    result.push_back(buf);
  }
}

void* TClientInfoCallHandler::getContext(const char* fn_name, void* serverContext) {
  if (serverContext) {
    TClientInfoConnection* callInfo =  static_cast<TClientInfoServerHandler::Connect*>(serverContext)->callInfo_;
    if (callInfo != nullptr) {
      callInfo->recordCall(fn_name);
    }
  }
  return nullptr;
}

} } } // namespace apache::thrift::server
