/**
 * 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 <gtest/gtest.h>

#include <sys/wait.h>

#include <string.h>

#include <list>
#include <string>

#include "docker/docker.hpp"

#include <process/gmock.hpp>
#include <process/gtest.hpp>

#include <stout/check.hpp>
#include <stout/error.hpp>
#include <stout/exit.hpp>
#include <stout/os.hpp>
#include <stout/strings.hpp>

#ifdef __linux__
#include "linux/cgroups.hpp"
#endif

#ifdef WITH_NETWORK_ISOLATOR
#include "linux/routing/utils.hpp"
#endif

#include "logging/logging.hpp"

#include "tests/environment.hpp"
#include "tests/flags.hpp"

#ifdef WITH_NETWORK_ISOLATOR
using namespace routing;
#endif

using std::list;
using std::string;

namespace mesos {
namespace internal {
namespace tests {

// Storage for the global environment instance.
Environment* environment;


// Returns true if we should enable the provided test. Similar to how
// tests can be disabled using the 'DISABLED_' prefix on a test case
// name or test name, we use:
//
//   'ROOT_' : Disable test if current user isn't root.
//   'CGROUPS_' : Disable test if cgroups support isn't present.
//   'NOHIERARCHY_' : Disable test if there is already a cgroups
//       hierarchy mounted.
//   'DOCKER_': Disable test if Docker is not supported.
//
// These flags can be composed in any order, but must come after
// 'DISABLED_'. In addition, we disable tests that attempt to use the
// CgroupsIsolator type parameter if the current user is not root or
// cgroups is not supported.
// TODO(benh): Provide a generic way to enable/disable tests by
// registering "filter" functions.
static bool enable(const ::testing::TestInfo& test)
{
  // First check the test case name and test name.
  list<string> names;
  names.push_back(test.test_case_name());
  names.push_back(test.name());

  Result<string> user = os::user();
  CHECK_SOME(user);

  foreach (const string& name, names) {
    if (strings::contains(name, "ROOT_") && user.get() != "root") {
      return false;
    }

    if (strings::contains(name, "CGROUPS_")) {
#ifdef __linux__
      if (!cgroups::enabled()) {
        return false;
      }
#else
      return false;
#endif
    }

#ifdef __linux__
    if (strings::contains(name, "NOHIERARCHY_")) {
      Try<std::set<std::string> > hierarchies = cgroups::hierarchies();
      CHECK_SOME(hierarchies);
      if (!hierarchies.get().empty()) {
        std::cerr
          << "-------------------------------------------------------------\n"
          << "We cannot run any cgroups tests that require mounting\n"
          << "hierarchies because you have the following hierarchies mounted:\n"
          << strings::trim(stringify(hierarchies.get()), " {},") << "\n"
          << "We'll disable the CgroupsNoHierarchyTest test fixture for now.\n"
          << "-------------------------------------------------------------"
          << std::endl;

        return false;
      }
    }

    // On Linux non-privileged users are limited to 64k of locked memory so we
    // cannot run the MemIsolatorTest.Usage.
    if (strings::contains(name, "MemIsolatorTest") && user.get() != "root") {
      return false;
    }
#endif

    // Filter out benchmark tests when we run 'make check'.
    if (strings::contains(name, "BENCHMARK_") && !flags.benchmark) {
      return false;
    }

    if (strings::contains(name, "DOCKER_")) {
#ifdef __linux__
      Try<Docker> docker = Docker::create(flags.docker);
      if (docker.isError()) {
        std::cerr
          << "-------------------------------------------------------------\n"
          << "Skipping Docker tests because validation failed\n"
          << "[Error] " + docker.error() + "\n"
          << "-------------------------------------------------------------"
          << std::endl;

        return false;
      }
#else
      return false;
#endif // __linux__
    }
  }

  // Filter out regular tests when we run 'make bench', which
  // requires us to check both the test case name and the test name
  // at the same time.
  if (flags.benchmark &&
      !strings::contains(test.test_case_name(), "BENCHMARK_") &&
      !strings::contains(test.name(), "BENCHMARK_")) {
    return false;
  }

  // Now check the type parameter.
  if (test.type_param() != NULL) {
    const string& type = test.type_param();
    if (strings::contains(type, "Cgroups")) {
#ifdef __linux__
      if (user.get() != "root" || !cgroups::enabled()) {
        return false;
      }
#else
      return false;
#endif
    }
  }

#ifdef WITH_NETWORK_ISOLATOR
  // We can not run network isolator.
  if (routing::check().isError() &&
      (strings::contains(test.name(), "PortMappingIsolatorTest") ||
       strings::contains(test.name(), "PortMappingMesosTest"))) {
      return false;
  }

  // Currently, the network isolator does not support multiple slaves.
  if (strings::contains(test.name(), "MultipleSlaves")) {
    return false;
  }
#endif

  return true;
}


// We use the constructor to setup specific tests by updating the
// gtest filter. We do this so that we can selectively run tests that
// require root or specific OS support (e.g., cgroups). Note that this
// should not effect any other filters that have been put in place
// either on the command line or via an environment variable.
// N.B. This MUST be done _before_ invoking RUN_ALL_TESTS.
Environment::Environment(const Flags& _flags) : flags(_flags)
{
  // First we split the current filter into enabled and disabled tests
  // (which are separated by a '-').
  const string& filter = ::testing::GTEST_FLAG(filter);

  // An empty filter indicates no tests should be run.
  if (filter.empty()) {
    return;
  }

  string enabled;
  string disabled;

  size_t dash = filter.find('-');
  if (dash != string::npos) {
    enabled = filter.substr(0, dash);
    disabled = filter.substr(dash + 1);
  } else {
    enabled = filter;
  }

  // Use universal filter if not specified.
  if (enabled.empty()) {
    enabled = "*";
  }

  // Ensure disabled tests end with ":" separator before we add more.
  if (!disabled.empty() && !strings::endsWith(disabled, ":")) {
    disabled += ":";
  }

  // Construct the filter string to handle system or platform specific tests.
  ::testing::UnitTest* unitTest = ::testing::UnitTest::GetInstance();
  for (int i = 0; i < unitTest->total_test_case_count(); i++) {
    const ::testing::TestCase* testCase = unitTest->GetTestCase(i);
    for (int j = 0; j < testCase->total_test_count(); j++) {
      const ::testing::TestInfo* testInfo = testCase->GetTestInfo(j);

      if (!enable(*testCase->GetTestInfo(j))) {
        // Append 'TestCase.TestName:'.
        disabled.append(testInfo->test_case_name());
        disabled.append(".");
        disabled.append(testInfo->name());
        disabled.append(":");
      }
    }
  }

  // Now update the gtest flag.
  ::testing::GTEST_FLAG(filter) = enabled + "-" + disabled;

  // Add our test event listeners.
  ::testing::TestEventListeners& listeners =
    ::testing::UnitTest::GetInstance()->listeners();

  listeners.Append(process::FilterTestEventListener::instance());
  listeners.Append(process::ClockTestEventListener::instance());
}


void Environment::SetUp()
{
  // Clear any MESOS_ environment variables so they don't affect our tests.
  char** environ = os::environ();
  for (int i = 0; environ[i] != NULL; i++) {
    std::string variable = environ[i];
    if (variable.find("MESOS_") == 0) {
      string key;
      size_t eq = variable.find_first_of("=");
      if (eq == string::npos) {
        continue; // Not expecting a missing '=', but ignore anyway.
      }
      os::unsetenv(variable.substr(strlen("MESOS_"), eq - strlen("MESOS_")));
    }
  }

  // Set the path to the native JNI library for running JVM tests.
  // TODO(tillt): Adapt library towards JNI specific name once libmesos
  // has been split.
  if (!os::hasenv("MESOS_NATIVE_JAVA_LIBRARY")) {
    string path = path::join(tests::flags.build_dir, "src", ".libs");
#ifdef __APPLE__
    path = path::join(path, "libmesos-" VERSION ".dylib");
#else
    path = path::join(path, "libmesos-" VERSION ".so");
#endif
    os::setenv("MESOS_NATIVE_JAVA_LIBRARY", path);
  }

  if (!GTEST_IS_THREADSAFE) {
    EXIT(1) << "Testing environment is not thread safe, bailing!";
  }
}


void Environment::TearDown()
{
  foreach (const string& directory, directories) {
    Try<Nothing> rmdir = os::rmdir(directory);
    if (rmdir.isError()) {
      LOG(ERROR) << "Failed to remove '" << directory
                 << "': " << rmdir.error();
    }
  }
  directories.clear();

  // Make sure we haven't left any child processes lying around.
  // TODO(benh): Look for processes in the same group or session that
  // might have been reparented.
  Try<os::ProcessTree> pstree = os::pstree(0);

  if (pstree.isSome() && !pstree.get().children.empty()) {
    FAIL() << "Tests completed with child processes remaining:\n"
           << pstree.get();
  }
}


Try<string> Environment::mkdtemp()
{
  const ::testing::TestInfo* const testInfo =
    ::testing::UnitTest::GetInstance()->current_test_info();

  if (testInfo == NULL) {
    return Error("Failed to determine the current test information");
  }

  // We replace any slashes present in the test names (e.g. TYPED_TEST),
  // to make sure the temporary directory resides under '/tmp/'.
  const string& testCase =
    strings::replace(testInfo->test_case_name(), "/", "_");

  string testName = strings::replace(testInfo->name(), "/", "_");

  // Adjust the test name to remove any 'DISABLED_' prefix (to make
  // things easier to read). While this might seem alarming, if we are
  // "running" a disabled test it must be the case that the test was
  // explicitly enabled (e.g., via 'gtest_filter').
  if (strings::startsWith(testName, "DISABLED_")) {
    testName = strings::remove(testName, "DISABLED_", strings::PREFIX);
  }

  const string& path =
    path::join("/tmp", strings::join("_", testCase, testName, "XXXXXX"));

  Try<string> mkdtemp = os::mkdtemp(path);
  if (mkdtemp.isSome()) {
    directories.push_back(mkdtemp.get());
  }
  return mkdtemp;
}

} // namespace tests {
} // namespace internal {
} // namespace mesos {
