/*
 * 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 <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 != NULL) {
    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 NULL;
  }
}

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 NULL;
  }
  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 NULL;
  }
  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_ == NULL) {
    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_ != NULL);
      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 == NULL) {
      continue;
    }

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

    timespec start;
    double secs = 0.0;
    info->getTime(&start);
    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 != NULL) {
      callInfo->recordCall(fn_name);
    }
  }
  return NULL;
}

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