// 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 "cobalt/base/localized_strings.h"

#include <libxml/parser.h>
#include <libxml/tree.h>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"

namespace base {

namespace {
// Does a DFS over the tree starting at |node| and ending at the first element
// whose name is |name|.
xmlNode* FindXmlNode(xmlNode* node, const char* name) {
  xmlNode* child = node->children;
  while (child) {
    if (child->type == XML_ELEMENT_NODE) {
      if (strcmp((const char*)child->name, name) == 0) {
        return child;
      }
      xmlNode* descendant = FindXmlNode(child, name);
      if (descendant) {
        return descendant;
      }
    }
    child = child->next;
  }
  return NULL;
}
}  // namespace

LocalizedStrings* LocalizedStrings::GetInstance() {
  return Singleton<LocalizedStrings>::get();
}

LocalizedStrings::LocalizedStrings() {
  // Initialize to US English on creation. A subsequent call to Initialize
  // will overwrite all available strings in the specified language.
  LoadStrings("en-US");
}

LocalizedStrings::~LocalizedStrings() {}

void LocalizedStrings::Initialize(const std::string& language) {
  LoadStrings(language);
}

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

void LocalizedStrings::LoadStrings(const std::string& language) {
  // Construct the XLB filename.
  FilePath xlb_path;
  PathService::Get(base::DIR_EXE, &xlb_path);
  xlb_path = xlb_path.Append("i18n").Append(language).AddExtension("xlb");

  // Try to open the XLB file.
  std::string content;
  if (!file_util::ReadFileToString(xlb_path, &content)) {
    DLOG(WARNING) << "Cannot open XLB file: " << xlb_path.value();

    // Fall back to a generic version of the same language.
    size_t dash = language.find('-');
    if (dash != std::string::npos) {
      // Chop off the country part of the language string and try again.
      std::string generic_lang(language.c_str(), dash);
      LoadStrings(generic_lang);
    }
    return;
  }

  // Parse the XML document.
  xmlDoc* doc = xmlParseDoc(reinterpret_cast<const xmlChar*>(content.c_str()));
  if (!doc) {
    DLOG(WARNING) << "Cannot parse XLB file: " << xlb_path.value();
    return;
  }

  // Find the first <msg> node by DFS.
  xmlNode* msg = FindXmlNode(xmlDocGetRootElement(doc), "msg");
  // Iterate through the sibling <msg> elements.
  while (msg) {
    if (!strcmp((const char*)msg->name, "msg")) {
      // Add the data from this element to the strings list.
      char* name =
          reinterpret_cast<char*>(xmlGetProp(msg, (const xmlChar*)"name"));
      char* value =
          reinterpret_cast<char*>(xmlNodeListGetString(doc, msg->children, 1));
      strings_[name] = value;
      xmlFree(name);
      xmlFree(value);
    }
    msg = msg->next;
  }

  xmlFreeDoc(doc);
}

}  // namespace base
