/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.
 */

#include "cobalt/base/log_message_handler.h"

#include "base/threading/thread_restrictions.h"

namespace base {

namespace {
// Checks whether this thread allows Singleton access. Some threads
// (e.g. detached threads, non-joinable threads) do not allow Singleton
// access, which means we cannot access our |LogMessageHandler| instance,
// nor even call |MessageLoop::current|.
bool DoesThreadAllowSingletons() {
  return ThreadRestrictions::GetSingletonAllowed();
}
}  // namespace

LogMessageHandler* LogMessageHandler::GetInstance() {
  return Singleton<LogMessageHandler,
                   StaticMemorySingletonTraits<LogMessageHandler> >::get();
}

LogMessageHandler::LogMessageHandler() {
  // Create the lock used to allow thread-safe checking of the thread.
  // Set the global log message handler to our static member function.
  old_log_message_handler_ = logging::GetLogMessageHandler();
  logging::SetLogMessageHandler(OnLogMessage);
}

LogMessageHandler::~LogMessageHandler() {
  logging::SetLogMessageHandler(old_log_message_handler_);
}

LogMessageHandler::CallbackId LogMessageHandler::AddCallback(
    const OnLogMessageCallback& callback) {
  AutoLock auto_lock(lock_);
  const CallbackId callback_id = next_callback_id_++;
  callbacks_[callback_id] = callback;
  return callback_id;
}

void LogMessageHandler::RemoveCallback(CallbackId callback_id) {
  AutoLock auto_lock(lock_);
  callbacks_.erase(callback_id);
}

// static
bool LogMessageHandler::OnLogMessage(int severity, const char* file, int line,
                                     size_t message_start,
                                     const std::string& str) {
  // If we are on a thread that doesn't support Singletons, we can't do
  // anything.
  if (!DoesThreadAllowSingletons()) {
    return false;
  }

  LogMessageHandler* instance = GetInstance();
  AutoLock auto_lock(instance->lock_);

  bool suppress = instance->suppress_log_output_;
  for (CallbackMap::const_iterator it = instance->callbacks_.begin();
       it != instance->callbacks_.end(); ++it) {
    if (it->second.Run(severity, file, line, message_start, str)) {
      suppress = true;
    }
  }

  return suppress;
}

void LogMessageHandler::SetSuppressLogOutput(bool suppress_log_output) {
  suppress_log_output_ = suppress_log_output;
}

bool LogMessageHandler::GetSuppressLogOutput() { return suppress_log_output_; }

}  // namespace base
