// 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/layout_tests/test_utils.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "cobalt/base/cobalt_paths.h"
#include "googleurl/src/gurl.h"

namespace cobalt {
namespace layout_tests {

namespace {

// Returns the relative path to Cobalt layout tests.  This can be appended
// to either base::DIR_SOURCE_ROOT to get the input directory or
// base::DIR_COBALT_TEST_OUT to get the output directory.
FilePath GetDirSourceRootRelativePath() {
  return FilePath(FILE_PATH_LITERAL("cobalt"))
      .Append(FILE_PATH_LITERAL("layout_tests"));
}

}  // namespace

FilePath GetTestInputRootDirectory() {
  FilePath dir_source_root;
  CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &dir_source_root));
  return dir_source_root.Append(GetDirSourceRootRelativePath());
}

FilePath GetTestOutputRootDirectory() {
  FilePath dir_cobalt_test_out;
  PathService::Get(cobalt::paths::DIR_COBALT_TEST_OUT, &dir_cobalt_test_out);
  return dir_cobalt_test_out.Append(GetDirSourceRootRelativePath());
}

LogFilter::LogFilter() {
  callback_id_ = base::LogMessageHandler::GetInstance()->AddCallback(
      base::Bind(&LogFilter::OnLogMessage, base::Unretained(this)));
}

LogFilter::~LogFilter() {
  base::LogMessageHandler::GetInstance()->RemoveCallback(callback_id_);
}

void LogFilter::Add(const std::string& s) { filtered_strings_.insert(s); }

bool LogFilter::OnLogMessage(int /*severity*/, const char* /*file*/,
                             int /*line*/, size_t message_start,
                             const std::string& str) {
  std::string trimmed_message = str.substr(message_start);
  TrimWhitespaceASCII(trimmed_message, TRIM_ALL, &trimmed_message);
  if (filtered_strings_.find(trimmed_message) != filtered_strings_.end()) {
    return true;
  } else {
    return false;
  }
}

}  // namespace layout_tests
}  // namespace cobalt
