// Copyright 2016 Google Inc. 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/shared/starboard/localized_strings.h"

#include "starboard/file.h"
#include "starboard/log.h"
#include "starboard/system.h"

namespace starboard {
namespace shared {
namespace starboard {

namespace {

std::string GetFilenameForLanguage(const std::string& language) {
  const int kBufferSize = 256;
  char buffer[kBufferSize];
  bool got_path =
      SbSystemGetPath(kSbSystemPathContentDirectory, buffer, kBufferSize);
  if (!got_path) {
    SB_DLOG(ERROR) << "Cannot get content path for i18n files.";
    return std::string();
  }

  return std::string(buffer).append("/i18n/").append(language).append(".csv");
}

bool ReadFile(const std::string& filename, std::string* out_result) {
  SB_DCHECK(filename.length() > 0);
  SB_DCHECK(out_result);

  ScopedFile file(filename.c_str(), kSbFileOpenOnly | kSbFileRead);
  if (!file.IsValid()) {
    SB_DLOG(WARNING) << "Cannot open i18n file: " << filename;
    return false;
  }

  SbFileInfo file_info = {0};
  bool got_info = file.GetInfo(&file_info);
  if (!got_info) {
    SB_DLOG(ERROR) << "Cannot get information for i18n file.";
    return false;
  }
  SB_DCHECK(file_info.size > 0);

  const int kMaxBufferSize = 16 * 1024;
  if (file_info.size > kMaxBufferSize) {
    SB_DLOG(ERROR) << "i18n file exceeds maximum size: " << file_info.size
                   << " (" << kMaxBufferSize << ")";
    return false;
  }

  char* buffer = new char[file_info.size];
  SB_DCHECK(buffer);
  int bytes_to_read = file_info.size;
  char* buffer_pos = buffer;
  while (bytes_to_read > 0) {
    int bytes_read = file.Read(buffer_pos, bytes_to_read);
    if (bytes_read < 0) {
      SB_DLOG(ERROR) << "Read from i18n file failed.";
      delete[] buffer;
      return false;
    }
    bytes_to_read -= bytes_read;
    buffer_pos += bytes_read;
  }

  *out_result = std::string(buffer, file_info.size);
  delete[] buffer;
  return true;
}

}  // namespace

LocalizedStrings::LocalizedStrings(const std::string& language) {
  bool did_load_strings = LoadStrings(language);

  if (!did_load_strings) {
    // Failed to load strings - try generic version of the language.
    size_t dash = language.find_first_of("-_");
    if (dash != std::string::npos) {
      std::string generic_lang(language.c_str(), dash);
      did_load_strings = LoadStrings(generic_lang);
    }
  }

  SB_DCHECK(did_load_strings);
}

std::string LocalizedStrings::GetString(const std::string& id,
                                        const std::string& fallback) const {
  StringMap::const_iterator iter = strings_.find(id);
  if (iter == strings_.end()) {
    return fallback;
  }
  return iter->second;
}

bool LocalizedStrings::LoadStrings(const std::string& language) {
  const std::string filename = GetFilenameForLanguage(language);
  std::string file_contents;
  if (!ReadFile(filename, &file_contents)) {
    SB_DLOG(ERROR) << "Error reading i18n file.";
    return false;
  }
  SB_DCHECK(file_contents.length() > 0);
  SB_DCHECK(file_contents.back() == '\n');

  // Each line of the file corresponds to one message (key/value).
  size_t pos = 0;
  while (true) {
    size_t next_pos = file_contents.find("\n", pos);
    if (next_pos == std::string::npos) {
      break;
    }
    bool got_string =
        LoadSingleString(std::string(file_contents, pos, next_pos - pos));
    SB_DCHECK(got_string);
    pos = next_pos + 1;
  }

  return true;
}

bool LocalizedStrings::LoadSingleString(const std::string& message) {
  // A single message is a key/value pair with separator.
  size_t separator_pos = message.find(';');
  if (separator_pos == std::string::npos) {
    SB_DLOG(ERROR) << "No separator found in: " << message;
    return false;
  }

  const std::string key(message, 0, separator_pos);
  const std::string value(message, separator_pos + 1);
  strings_[key] = value;
  return true;
}

}  // namespace starboard
}  // namespace shared
}  // namespace starboard
