// Copyright 2017 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 <sys/utsname.h>

#include <cstring>
#include <memory>
#include <string>

#include "starboard/common/format_string.h"
#include "starboard/common/log.h"
#include "starboard/common/string.h"

namespace {

const char* kBrandName = "Raspberry Pi Foundation";

const char* kModelRevision = "Rev";

const char* kFriendlyName = "Raspberry Pi";

// Read device model from /proc/device-tree/model
const char* GetModelName() {
  const char* file_path = "/proc/device-tree/model";
  // Size of the raw data
  size_t file_data_size;

  file_data_size = 0;
  // Get the size of the file by reading it until the end. This is
  // required because files under /proc do not always return a valid size
  // when using fseek(0, SEEK_END) + ftell(). Nor can the be mmap()-ed.
  FILE* file = fopen(file_path, "r");
  if (file != nullptr) {
    for (;;) {
      char file_buffer[256];
      size_t data_size = fread(file_buffer, 1, sizeof(file_buffer), file);
      if (data_size == 0) {
        break;
      }
      file_data_size += data_size;
    }
    fclose(file);
  }

  const size_t kFileSizeCap = 1000;
  if (file_data_size > kFileSizeCap) {
    SB_LOG(ERROR)
        << "File too large: /proc/device-tree/model is larger than 1KB.";
    return "";
  }

  // Read the contents of the /proc/device-tree/model file.
  const size_t kFileDataSize = file_data_size + 1;
  char file_data[kFileDataSize];
  char* file_data_ptr = file_data;
  memset(file_data_ptr, 0, file_data_size + 1);

  file = fopen(file_path, "r");
  if (file != nullptr) {
    for (size_t offset = 0; offset < file_data_size;) {
      size_t data_size =
          fread(file_data_ptr + offset, 1, file_data_size - offset, file);
      if (data_size == 0) {
        break;
      }
      offset += data_size;
    }
    fclose(file);
  }

  // Zero-terminate the first line of the file because the model name is in the
  // first line
  for (int i = 0; i < file_data_size; i++) {
    if (file_data_ptr[i] == '\n') {
      file_data_ptr[i] = '\0';
      break;
    }
  }

  // Zero-terminate the file data
  file_data_ptr[file_data_size] = '\0';

  // Get Model name
  std::string model_string(const_cast<char*>(file_data));
  std::string model_name;

  // Find the revision number of the model name and remove it if present
  int model_rev_pos = model_string.find(kModelRevision);
  if (model_rev_pos != std::string::npos) {
    model_name = model_string.substr(0, model_rev_pos);
  }

  // Trim trailing spaces
  size_t end = model_name.find_last_not_of(" \t");
  if (end != std::string::npos) {
    return model_name.substr(0, end + 1).c_str();
  } else {
    return "";
  }
}

bool CopyStringAndTestIfSuccess(char* out_value,
                                int value_length,
                                const char* from_value) {
  if (SbStringGetLength(from_value) + 1 > value_length)
    return false;
  SbStringCopy(out_value, from_value, value_length);
  return true;
}

}  // namespace

bool SbSystemGetProperty(SbSystemPropertyId property_id,
                         char* out_value,
                         int value_length) {
  if (!out_value || !value_length) {
    return false;
  }

  switch (property_id) {
    case kSbSystemPropertyBrandName:
      return CopyStringAndTestIfSuccess(out_value, value_length, kBrandName);

    case kSbSystemPropertyModelName:
      return CopyStringAndTestIfSuccess(out_value, value_length,
                                        GetModelName());

    case kSbSystemPropertyChipsetModelNumber:
    case kSbSystemPropertyFirmwareVersion:
    case kSbSystemPropertyModelYear:
#if SB_API_VERSION >= 12
    case kSbSystemPropertySystemIntegratorName:
#elif SB_API_VERSION == 11
    case kSbSystemPropertyOriginalDesignManufacturerName:
#else
    case kSbSystemPropertyNetworkOperatorName:
#endif
    case kSbSystemPropertySpeechApiKey:
      return false;

    case kSbSystemPropertyFriendlyName:
      return CopyStringAndTestIfSuccess(out_value, value_length, kFriendlyName);

    case kSbSystemPropertyPlatformName: {
      // Example output: "Raspian Linux armv7l".
      utsname name;

      if (uname(&name) == -1)
        return false;

      std::string temp =
          starboard::FormatString("Raspian %s %s", name.sysname, name.machine);

      return CopyStringAndTestIfSuccess(out_value, value_length, temp.c_str());
    }

    default:
      SB_DLOG(WARNING) << __FUNCTION__
                       << ": Unrecognized property: " << property_id;
      break;
  }

  return false;
}
