// Copyright 2015 The Cobalt Authors. 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
