// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_BIN_PLATFORM_H_
#define RUNTIME_BIN_PLATFORM_H_

#include "bin/builtin.h"

#include "platform/atomic.h"
#include "platform/globals.h"
#include "platform/utils.h"

#if defined(DART_HOST_OS_MACOS)
#include "bin/platform_macos.h"
#endif  // defined(DART_HOST_OS_MACOS)

namespace dart {
namespace bin {

class Platform {
 public:
  // Perform platform specific initialization.
  static bool Initialize();

  // Returns the number of processors on the machine.
  static int NumberOfProcessors();

  // Returns a string representing the operating system ("linux",
  // "macos", "windows", or "android"). The returned string should not be
  // deallocated by the caller.
  static const char* OperatingSystem();

  // Returns a string representing the version of the operating system. The
  // format of the string is determined by the platform. The returned string
  // should not be deallocated by the caller.
  static const char* OperatingSystemVersion();

  // Returns the architecture name of the processor the VM is running on
  // (ia32, x64, arm, or arm64).
  static const char* HostArchitecture() {
#if defined(HOST_ARCH_ARM)
    return "arm";
#elif defined(HOST_ARCH_ARM64)
    return "arm64";
#elif defined(HOST_ARCH_IA32)
    return "ia32";
#elif defined(HOST_ARCH_X64)
    return "x64";
#else
#error Architecture detection failed.
#endif
  }

  static const char* LibraryPrefix();

  // Returns a string representing the operating system's shared library
  // extension (e.g. 'so', 'dll', ...). The returned string should not be
  // deallocated by the caller.
  static const char* LibraryExtension();

  // Extracts the local hostname.
  static bool LocalHostname(char* buffer, intptr_t buffer_length);

  static const char* LocaleName();

  // Extracts the environment variables for the current process.  The array of
  // strings is Dart_ScopeAllocated. The number of elements in the array is
  // returned in the count argument.
  static char** Environment(intptr_t* count);

  static const char* ResolveExecutablePath();

  // This has the same effect as calling ResolveExecutablePath except that
  // Dart_ScopeAllocate is not called and that the result goes into the given
  // parameters.
  // WARNING: On Fuchsia it returns -1, i.e. doesn't work.
  // Note that `result` should be pre-allocated with size `result_size`.
  // The return-value is the length read into `result` or -1 on failure.
  static intptr_t ResolveExecutablePathInto(char* result, size_t result_size);

  // Stores the executable name.
  static void SetExecutableName(const char* executable_name) {
    executable_name_ = executable_name;
  }
  static const char* GetExecutableName();
  static const char* GetResolvedExecutableName() {
    if (resolved_executable_name_.load() == nullptr) {
      // Try to resolve the executable path using platform specific APIs.
      const char* resolved_name = Platform::ResolveExecutablePath();
      if (resolved_name != nullptr) {
        char* resolved_name_copy = Utils::StrDup(resolved_name);
        const char* expect_old_is_null = nullptr;
        if (!resolved_executable_name_.compare_exchange_strong(
                expect_old_is_null, resolved_name_copy)) {
          free(resolved_name_copy);
        }
      }
    }
    return resolved_executable_name_.load();
  }

  // Stores and gets the flags passed to the executable.
  static void SetExecutableArguments(int script_index, char** argv) {
    script_index_ = script_index;
    argv_ = argv;
  }
  static int GetScriptIndex() { return script_index_; }
  static char** GetArgv() { return argv_; }

  static void SetProcessName(const char* name);

  DART_NORETURN static void Exit(int exit_code);

  static void SetCoreDumpResourceLimit(int value);

 private:
  // The path to the executable.
  static const char* executable_name_;

  // The path to the resolved executable.
  //
  // We use require-release semantics to ensure initializing stores to the
  // string are visible when the string becomes visible.
  static AcqRelAtomic<const char*> resolved_executable_name_;

  static int script_index_;
  static char** argv_;  // VM flags are argv_[1 ... script_index_ - 1]

  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(Platform);
};

}  // namespace bin
}  // namespace dart

#endif  // RUNTIME_BIN_PLATFORM_H_
