// Copyright 2015 The Crashpad 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 "test/test_paths.h"

#include <stdlib.h>
#include <sys/stat.h>

#include "base/logging.h"
#include "build/build_config.h"
#include "util/misc/paths.h"

namespace crashpad {
namespace test {

namespace {

bool IsTestDataRoot(const base::FilePath& candidate) {
  const base::FilePath marker_path =
      candidate.Append(FILE_PATH_LITERAL("test"))
          .Append(FILE_PATH_LITERAL("test_paths_test_data_root.txt"));

#if !BUILDFLAG(IS_WIN)
  struct stat stat_buf;
  int rv = stat(marker_path.value().c_str(), &stat_buf);
#else
  struct _stat stat_buf;
  int rv = _wstat(marker_path.value().c_str(), &stat_buf);
#endif

  return rv == 0;
}

base::FilePath TestDataRootInternal() {
#if BUILDFLAG(IS_FUCHSIA)
  base::FilePath asset_path("/pkg/data");
  if (!IsTestDataRoot(asset_path)) {
    LOG(WARNING) << "test data root seems invalid, continuing anyway";
  }
  return asset_path;
#else  // BUILDFLAG(IS_FUCHSIA)
#if !BUILDFLAG(IS_WIN)
  const char* environment_value = getenv("CRASHPAD_TEST_DATA_ROOT");
#else  // BUILDFLAG(IS_WIN)
  const wchar_t* environment_value = _wgetenv(L"CRASHPAD_TEST_DATA_ROOT");
#endif

  if (environment_value) {
    // It was specified explicitly, so use it even if it seems incorrect.
    if (!IsTestDataRoot(base::FilePath(environment_value))) {
      LOG(WARNING) << "CRASHPAD_TEST_DATA_ROOT seems invalid, honoring anyway";
    }

    return base::FilePath(environment_value);
  }

  base::FilePath executable_path;
  if (Paths::Executable(&executable_path)) {
#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
    // On Android and iOS, test data is in a crashpad_test_data directory
    // adjacent to the main executable. On iOS, this refers to the main
    // executable file inside the .app bundle, so crashpad_test_data is also
    // inside the bundle.
    base::FilePath candidate = executable_path.DirName()
                               .Append("crashpad_test_data");
#else  // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDRID)
    // In a standalone build, the test executable is usually at
    // out/{Debug,Release} relative to the Crashpad root.
    base::FilePath candidate =
        base::FilePath(executable_path.DirName()
                           .Append(base::FilePath::kParentDirectory)
                           .Append(base::FilePath::kParentDirectory));
#endif  // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID)
    if (IsTestDataRoot(candidate)) {
      return candidate;
    }

    // In an in-Chromium build, the test executable is usually at
    // out/{Debug,Release} relative to the Chromium root, and the Crashpad root
    // is at third_party/crashpad/crashpad relative to the Chromium root.
    candidate = candidate.Append(FILE_PATH_LITERAL("third_party"))
                    .Append(FILE_PATH_LITERAL("crashpad"))
                    .Append(FILE_PATH_LITERAL("crashpad"));
    if (IsTestDataRoot(candidate)) {
      return candidate;
    }
  }

  // If nothing else worked, use the current directory, issuing a warning if it
  // doesn’t seem right.
  if (!IsTestDataRoot(base::FilePath(base::FilePath::kCurrentDirectory))) {
    LOG(WARNING) << "could not locate a valid test data root";
  }

  return base::FilePath(base::FilePath::kCurrentDirectory);
#endif  // BUILDFLAG(IS_FUCHSIA)
}

#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS)

// Returns the pathname of a directory containing 32-bit test build output.
//
// It would be better for this to be named 32BitOutputDirectory(), but that’s
// not a legal name.
base::FilePath Output32BitDirectory() {
  const wchar_t* environment_value = _wgetenv(L"CRASHPAD_TEST_32_BIT_OUTPUT");
  if (!environment_value) {
    return base::FilePath();
  }

  return base::FilePath(environment_value);
}

#endif  // BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS)

}  // namespace

// static
base::FilePath TestPaths::Executable() {
  base::FilePath executable_path;
  CHECK(Paths::Executable(&executable_path));
#if defined(CRASHPAD_IS_IN_FUCHSIA)
  executable_path = base::FilePath("/pkg/bin/app");
#endif
  return executable_path;
}

// static
base::FilePath TestPaths::ExpectedExecutableBasename(
    const base::FilePath::StringType& name) {
#if BUILDFLAG(IS_FUCHSIA)
  // Apps in Fuchsia packages are always named "app".
  return base::FilePath("app");
#else  // BUILDFLAG(IS_FUCHSIA)
#if defined(CRASHPAD_IS_IN_CHROMIUM)
  base::FilePath::StringType executable_name(
      FILE_PATH_LITERAL("crashpad_tests"));
#else  // CRASHPAD_IS_IN_CHROMIUM
  base::FilePath::StringType executable_name(name);
#endif  // CRASHPAD_IS_IN_CHROMIUM

#if BUILDFLAG(IS_WIN)
  executable_name += FILE_PATH_LITERAL(".exe");
#endif  // BUILDFLAG(IS_WIN)

  return base::FilePath(executable_name);
#endif  // BUILDFLAG(IS_FUCHSIA)
}

// static
base::FilePath TestPaths::TestDataRoot() {
  static base::FilePath* test_data_root =
      new base::FilePath(TestDataRootInternal());
  return *test_data_root;
}

// static
base::FilePath TestPaths::BuildArtifact(
    const base::FilePath::StringType& module,
    const base::FilePath::StringType& artifact,
    FileType file_type,
    Architecture architecture) {
  base::FilePath directory;
  switch (architecture) {
    case Architecture::kDefault:
      directory = Executable().DirName();
      break;

#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS)
    case Architecture::k32Bit:
      directory = Output32BitDirectory();
      CHECK(!directory.empty());
      break;
#endif  // BUILDFLAG(IS_WIN) && ARCH_CPU_64_BITS
  }

  base::FilePath::StringType test_name =
      FILE_PATH_LITERAL("crashpad_") + module + FILE_PATH_LITERAL("_test");
#if !defined(CRASHPAD_IS_IN_CHROMIUM) && !BUILDFLAG(IS_FUCHSIA)
  CHECK(Executable().BaseName().RemoveFinalExtension().value() == test_name);
#endif  // !CRASHPAD_IS_IN_CHROMIUM

  base::FilePath::StringType extension;
  switch (file_type) {
    case FileType::kNone:
      break;

    case FileType::kExecutable:
#if BUILDFLAG(IS_WIN)
      extension = FILE_PATH_LITERAL(".exe");
#elif BUILDFLAG(IS_FUCHSIA)
      directory = base::FilePath(FILE_PATH_LITERAL("/pkg/bin"));
#endif  // BUILDFLAG(IS_WIN)
      break;

    case FileType::kLoadableModule:
#if BUILDFLAG(IS_WIN)
      extension = FILE_PATH_LITERAL(".dll");
#else  // BUILDFLAG(IS_WIN)
      extension = FILE_PATH_LITERAL(".so");
#endif  // BUILDFLAG(IS_WIN)

#if BUILDFLAG(IS_FUCHSIA)
      // TODO(scottmg): .so files are currently deployed into /boot/lib, where
      // they'll be found (without a path) by the loader. Application packaging
      // infrastructure is in progress, so this will likely change again in the
      // future.
      directory = base::FilePath();
#endif
      break;

    case FileType::kCertificate:
#if defined(CRASHPAD_IS_IN_FUCHSIA)
      directory = base::FilePath(FILE_PATH_LITERAL("/pkg/data"));
#endif
      extension = FILE_PATH_LITERAL(".pem");
      break;
  }

  return directory.Append(test_name + FILE_PATH_LITERAL("_") + artifact +
                          extension);
}

#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS)

// static
bool TestPaths::Has32BitBuildArtifacts() {
  return !Output32BitDirectory().empty();
}

#endif  // BUILDFLAG(IS_WIN) && defined(ARCH_CPU_64_BITS)

}  // namespace test
}  // namespace crashpad
