// Copyright 2013 Google Inc.
//
// 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.

// Author: oschaaf@gmail.com (Otto van der Schaaf)

#include "ngx_message_handler.h"

#include <signal.h>

#include "net/instaweb/util/public/abstract_mutex.h"
#include "net/instaweb/util/public/debug.h"
#include "net/instaweb/util/public/shared_circular_buffer.h"
#include "net/instaweb/util/public/string_util.h"
#include "net/instaweb/public/version.h"
#include "pagespeed/kernel/base/posix_timer.h"
#include "pagespeed/kernel/base/time_util.h"

namespace {

// This will be prefixed to every logged message.
const char kModuleName[] = "ngx_pagespeed";

// If set, the crash handler will use this to output a backtrace using
// ngx_log_error.
ngx_log_t* global_log = NULL;

}  // namespace

extern "C" {
  static void signal_handler(int sig) {
    // Try to output the backtrace to the log file. Since this may end up
    // crashing/deadlocking/etc. we set an alarm() to abort us if it comes to
    // that.
    alarm(2);
    if (global_log != NULL) {
      ngx_log_error(NGX_LOG_ALERT, global_log, 0, "Trapped signal [%d]\n%s",
                    sig, net_instaweb::StackTraceString().c_str());
    } else {
      fprintf(stderr, "Trapped signal [%d]\n%s\n",
              sig, net_instaweb::StackTraceString().c_str());
    }
    kill(getpid(), SIGKILL);
  }
}  // extern "C"

namespace net_instaweb {

NgxMessageHandler::NgxMessageHandler(Timer* timer, AbstractMutex* mutex)
    : SystemMessageHandler(timer, mutex),
      log_(NULL) {
}

// Installs a signal handler for common crash signals, that tries to print
// out a backtrace.
void NgxMessageHandler::InstallCrashHandler(ngx_log_t* log) {
  global_log = log;
  signal(SIGTRAP, signal_handler);  // On check failures
  signal(SIGABRT, signal_handler);
  signal(SIGFPE, signal_handler);
  signal(SIGSEGV, signal_handler);
}

ngx_uint_t NgxMessageHandler::GetNgxLogLevel(MessageType type) {
  switch (type) {
    case kInfo:
      return NGX_LOG_INFO;
    case kWarning:
      return NGX_LOG_WARN;
    case kError:
      return NGX_LOG_ERR;
    case kFatal:
      return NGX_LOG_ALERT;
  }

  // This should never fall through, but some compilers seem to complain if
  // we don't include this.
  return NGX_LOG_ALERT;
}

void NgxMessageHandler::MessageVImpl(MessageType type, const char* msg,
                                     va_list args) {
  ngx_uint_t log_level = GetNgxLogLevel(type);
  GoogleString formatted_message = Format(msg, args);
  if (log_ != NULL) {
    ngx_log_error(log_level, log_, 0/*ngx_err_t*/, "[%s %s] %s",
                  kModuleName, kModPagespeedVersion, formatted_message.c_str());
  } else {
    GoogleMessageHandler::MessageVImpl(type, msg, args);
  }
  // Prepare a log message for the SharedCircularBuffer only.
  AddMessageToBuffer(type, formatted_message);
}

void NgxMessageHandler::FileMessageVImpl(MessageType type, const char* file,
                                         int line, const char* msg,
                                         va_list args) {
  ngx_uint_t log_level = GetNgxLogLevel(type);
  GoogleString formatted_message = Format(msg, args);
  if (log_ != NULL) {
    ngx_log_error(log_level, log_, 0/*ngx_err_t*/, "[%s %s] %s:%d:%s",
                  kModuleName, kModPagespeedVersion, file, line,
                  formatted_message.c_str());
  } else {
    GoogleMessageHandler::FileMessageVImpl(type, file, line, msg, args);
  }
}

}  // namespace net_instaweb
