// 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 "starboard/system.h"

#include <linux/limits.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <cstring>
#include <vector>

#include "starboard/common/log.h"
#include "starboard/common/string.h"
#include "starboard/configuration_constants.h"
#include "starboard/directory.h"
#include "starboard/user.h"

namespace {
const int kMaxPathSize = kSbFileMaxPath;

// Gets the path to the cache directory, using the user's home directory.
bool GetCacheDirectory(char* out_path, int path_size) {
  std::vector<char> home_path(kMaxPathSize + 1);
  if (!SbUserGetProperty(SbUserGetCurrent(), kSbUserPropertyHomeDirectory,
                         home_path.data(), kMaxPathSize)) {
    return false;
  }
  int result =
      SbStringFormatF(out_path, path_size, "%s/.cache", home_path.data());
  if (result < 0 || result >= path_size) {
    out_path[0] = '\0';
    return false;
  }
  return SbDirectoryCreate(out_path);
}

// Gets the path to the storage directory, using the user's home directory.
bool GetStorageDirectory(char* out_path, int path_size) {
  std::vector<char> home_path(kMaxPathSize + 1);
  if (!SbUserGetProperty(SbUserGetCurrent(), kSbUserPropertyHomeDirectory,
                         home_path.data(), kMaxPathSize)) {
    return false;
  }
  int result = SbStringFormatF(out_path, path_size, "%s/.cobalt_storage",
                               home_path.data());
  if (result < 0 || result >= path_size) {
    out_path[0] = '\0';
    return false;
  }
  return SbDirectoryCreate(out_path);
}

// Places up to |path_size| - 1 characters of the path to the current
// executable in |out_path|, ensuring it is NULL-terminated. Returns success
// status. The result being greater than |path_size| - 1 characters is a
// failure. |out_path| may be written to in unsuccessful cases.
bool GetExecutablePath(char* out_path, int path_size) {
  if (path_size < 1) {
    return false;
  }

  std::vector<char> path(kMaxPathSize + 1);
  ssize_t bytes_read = readlink("/proc/self/exe", path.data(), kMaxPathSize);
  if (bytes_read < 1) {
    return false;
  }

  path[bytes_read] = '\0';
  if (bytes_read >= path_size) {
    return false;
  }

  SbStringCopy(out_path, path.data(), path_size);
  return true;
}

// Places up to |path_size| - 1 characters of the path to the directory
// containing the current executable in |out_path|, ensuring it is
// NULL-terminated. Returns success status. The result being greater than
// |path_size| - 1 characters is a failure. |out_path| may be written to in
// unsuccessful cases.
bool GetExecutableDirectory(char* out_path, int path_size) {
  if (!GetExecutablePath(out_path, path_size)) {
    return false;
  }

  char* last_slash =
      const_cast<char *>(SbStringFindLastCharacter(out_path, '/'));
  if (!last_slash) {
    return false;
  }

  *last_slash = '\0';
  return true;
}

// Gets only the name portion of the current executable.
bool GetExecutableName(char* out_path, int path_size) {
  std::vector<char> path(kMaxPathSize, 0);
  if (!GetExecutablePath(path.data(), kMaxPathSize)) {
    return false;
  }

  const char* last_slash = SbStringFindLastCharacter(path.data(), '/');
  if (SbStringCopy(out_path, last_slash + 1, path_size) >= path_size) {
    return false;
  }
  return true;
}

// Gets the path to a temporary directory that is unique to this process.
bool GetTemporaryDirectory(char* out_path, int path_size) {
  std::vector<char> binary_name(kMaxPathSize, 0);
  if (!GetExecutableName(binary_name.data(), kMaxPathSize)) {
    return false;
  }

  int result = SbStringFormatF(out_path, path_size, "/tmp/%s-%d",
                               binary_name.data(), static_cast<int>(getpid()));
  if (result < 0 || result >= path_size) {
    out_path[0] = '\0';
    return false;
  }

  return true;
}
}  // namespace

bool SbSystemGetPath(SbSystemPathId path_id, char* out_path, int path_size) {
  if (!out_path || !path_size) {
    return false;
  }

  const int kPathSize = kSbFileMaxPath;
  std::vector<char> path(kPathSize);
  path[0] = '\0';

  switch (path_id) {
    case kSbSystemPathContentDirectory:
      if (!GetExecutableDirectory(path.data(), kPathSize)) {
        return false;
      }
      if (SbStringConcat(path.data(), "/content", kPathSize) >= kPathSize) {
        return false;
      }
      break;

    case kSbSystemPathCacheDirectory:
      if (!GetCacheDirectory(path.data(), kPathSize)) {
        return false;
      }
      if (SbStringConcat(path.data(), "/cobalt", kPathSize) >= kPathSize) {
        return false;
      }
      if (!SbDirectoryCreate(path.data())) {
        return false;
      }
      break;

    case kSbSystemPathDebugOutputDirectory:
      if (!SbSystemGetPath(kSbSystemPathTempDirectory, path.data(),
                           kPathSize)) {
        return false;
      }
      if (SbStringConcat(path.data(), "/log", kPathSize) >= kPathSize) {
        return false;
      }
      SbDirectoryCreate(path.data());
      break;

    case kSbSystemPathTempDirectory:
      if (!GetTemporaryDirectory(path.data(), kPathSize)) {
        return false;
      }
      SbDirectoryCreate(path.data());
      break;

    case kSbSystemPathTestOutputDirectory:
      return SbSystemGetPath(kSbSystemPathDebugOutputDirectory, out_path,
                             path_size);

    case kSbSystemPathExecutableFile:
      return GetExecutablePath(out_path, path_size);

    case kSbSystemPathFontConfigurationDirectory:
    case kSbSystemPathFontDirectory:
        return false;

#if SB_API_VERSION >= SB_STORAGE_PATH_VERSION
    case kSbSystemPathStorageDirectory:
      if (!GetStorageDirectory(path.data(), kPathSize)) {
        return false;
      }
      break;
#endif

    default:
      SB_NOTIMPLEMENTED() << "SbSystemGetPath not implemented for "
                          << path_id;
      return false;
  }

  int length = SbStringGetLength(path.data());
  if (length < 1 || length > path_size) {
    return false;
  }

  SbStringCopy(out_path, path.data(), path_size);
  return true;
}
