// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/character_encoding.h"

#include <map>
#include <set>

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/icu/source/common/unicode/ucnv.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_collator.h"

using content::BrowserThread;

namespace {

// The maximum length of short list of recently user selected encodings is 3.
const size_t kUserSelectedEncodingsMaxLength = 3;

typedef struct {
  int resource_id;
  const char* name;
  int category_string_id;
} CanonicalEncodingData;

// An array of all supported canonical encoding names.
const CanonicalEncodingData kCanonicalEncodingNames[] = {
  { IDC_ENCODING_UTF8, "UTF-8", IDS_ENCODING_UNICODE },
  { IDC_ENCODING_UTF16LE, "UTF-16LE", IDS_ENCODING_UNICODE },
  { IDC_ENCODING_WINDOWS1252, "windows-1252", IDS_ENCODING_WESTERN },
  { IDC_ENCODING_GBK, "GBK", IDS_ENCODING_SIMP_CHINESE },
  { IDC_ENCODING_GB18030, "gb18030", IDS_ENCODING_SIMP_CHINESE },
  { IDC_ENCODING_BIG5, "Big5", IDS_ENCODING_TRAD_CHINESE },
  { IDC_ENCODING_BIG5HKSCS, "Big5-HKSCS", IDS_ENCODING_TRAD_CHINESE },
  { IDC_ENCODING_KOREAN, "EUC-KR", IDS_ENCODING_KOREAN },
  { IDC_ENCODING_SHIFTJIS, "Shift_JIS", IDS_ENCODING_JAPANESE },
  { IDC_ENCODING_EUCJP, "EUC-JP", IDS_ENCODING_JAPANESE },
  { IDC_ENCODING_ISO2022JP, "ISO-2022-JP", IDS_ENCODING_JAPANESE },
  { IDC_ENCODING_THAI, "windows-874", IDS_ENCODING_THAI },
  { IDC_ENCODING_ISO885915, "ISO-8859-15", IDS_ENCODING_WESTERN },
  { IDC_ENCODING_MACINTOSH, "macintosh", IDS_ENCODING_WESTERN },
  { IDC_ENCODING_ISO88592, "ISO-8859-2", IDS_ENCODING_CENTRAL_EUROPEAN },
  { IDC_ENCODING_WINDOWS1250, "windows-1250", IDS_ENCODING_CENTRAL_EUROPEAN },
  { IDC_ENCODING_ISO88595, "ISO-8859-5", IDS_ENCODING_CYRILLIC },
  { IDC_ENCODING_WINDOWS1251, "windows-1251", IDS_ENCODING_CYRILLIC },
  { IDC_ENCODING_KOI8R, "KOI8-R", IDS_ENCODING_CYRILLIC },
  { IDC_ENCODING_KOI8U, "KOI8-U", IDS_ENCODING_CYRILLIC },
  { IDC_ENCODING_ISO88597, "ISO-8859-7", IDS_ENCODING_GREEK },
  { IDC_ENCODING_WINDOWS1253, "windows-1253", IDS_ENCODING_GREEK },
  { IDC_ENCODING_WINDOWS1254, "windows-1254", IDS_ENCODING_TURKISH },
  { IDC_ENCODING_WINDOWS1256, "windows-1256", IDS_ENCODING_ARABIC },
  { IDC_ENCODING_ISO88596, "ISO-8859-6", IDS_ENCODING_ARABIC },
  { IDC_ENCODING_WINDOWS1255, "windows-1255", IDS_ENCODING_HEBREW },
  { IDC_ENCODING_ISO88598I, "ISO-8859-8-I", IDS_ENCODING_HEBREW },
  { IDC_ENCODING_ISO88598, "ISO-8859-8", IDS_ENCODING_HEBREW },
  { IDC_ENCODING_WINDOWS1258, "windows-1258", IDS_ENCODING_VIETNAMESE },
  { IDC_ENCODING_ISO88594, "ISO-8859-4", IDS_ENCODING_BALTIC },
  { IDC_ENCODING_ISO885913, "ISO-8859-13", IDS_ENCODING_BALTIC },
  { IDC_ENCODING_WINDOWS1257, "windows-1257", IDS_ENCODING_BALTIC },
  { IDC_ENCODING_ISO88593, "ISO-8859-3", IDS_ENCODING_SOUTH_EUROPEAN },
  { IDC_ENCODING_ISO885910, "ISO-8859-10", IDS_ENCODING_NORDIC },
  { IDC_ENCODING_ISO885914, "ISO-8859-14", IDS_ENCODING_CELTIC },
  { IDC_ENCODING_ISO885916, "ISO-8859-16", IDS_ENCODING_ROMANIAN },
};

const int kCanonicalEncodingNamesLength = arraysize(kCanonicalEncodingNames);

typedef std::map<int, std::pair<const char*, int> >
    IdToCanonicalEncodingNameMapType;
typedef std::map<const std::string, int> CanonicalEncodingNameToIdMapType;

typedef struct {
  const char* canonical_form;
  const char* display_form;
} CanonicalEncodingDisplayNamePair;

const CanonicalEncodingDisplayNamePair kCanonicalDisplayNameOverrides[] = {
  // Only lists the canonical names where we want a different form for display.
  { "macintosh", "Macintosh" },
  { "windows-874", "Windows-874" },
  { "windows-1250", "Windows-1250" },
  { "windows-1251", "Windows-1251" },
  { "windows-1252", "Windows-1252" },
  { "windows-1253", "Windows-1253" },
  { "windows-1254", "Windows-1254" },
  { "windows-1255", "Windows-1255" },
  { "windows-1256", "Windows-1256" },
  { "windows-1257", "Windows-1257" },
  { "windows-1258", "Windows-1258" },
};

const int kCanonicalDisplayNameOverridesLength =
    arraysize(kCanonicalDisplayNameOverrides);

typedef std::map<std::string, const char*> CanonicalNameDisplayNameMapType;

class CanonicalEncodingMap {
 public:
  CanonicalEncodingMap() {}
  const IdToCanonicalEncodingNameMapType* GetIdToCanonicalEncodingNameMapData();
  const CanonicalEncodingNameToIdMapType* GetCanonicalEncodingNameToIdMapData();
  const CanonicalNameDisplayNameMapType* GetCanonicalNameDisplayNameMapData();
  std::vector<int>* locale_dependent_encoding_ids() {
    return &locale_dependent_encoding_ids_;
  }

  std::vector<CharacterEncoding::EncodingInfo>* current_display_encodings() {
    return &current_display_encodings_;
  }

 private:
  scoped_ptr<IdToCanonicalEncodingNameMapType> id_to_encoding_name_map_;
  scoped_ptr<CanonicalEncodingNameToIdMapType> encoding_name_to_id_map_;
  scoped_ptr<CanonicalNameDisplayNameMapType>
      encoding_name_to_display_name_map_;
  std::vector<int> locale_dependent_encoding_ids_;
  std::vector<CharacterEncoding::EncodingInfo> current_display_encodings_;

  DISALLOW_COPY_AND_ASSIGN(CanonicalEncodingMap);
};

const IdToCanonicalEncodingNameMapType*
    CanonicalEncodingMap::GetIdToCanonicalEncodingNameMapData() {
  // Testing and building map is not thread safe, this function is supposed to
  // only run in UI thread. Myabe I should add a lock in here for making it as
  // thread safe.
  if (!id_to_encoding_name_map_.get()) {
    id_to_encoding_name_map_.reset(new IdToCanonicalEncodingNameMapType);
    for (int i = 0; i < kCanonicalEncodingNamesLength; ++i) {
      int resource_id = kCanonicalEncodingNames[i].resource_id;
      (*id_to_encoding_name_map_)[resource_id] =
        std::make_pair(kCanonicalEncodingNames[i].name,
                       kCanonicalEncodingNames[i].category_string_id);
    }
  }
  return id_to_encoding_name_map_.get();
}

const CanonicalEncodingNameToIdMapType*
    CanonicalEncodingMap::GetCanonicalEncodingNameToIdMapData() {
  if (!encoding_name_to_id_map_.get()) {
    encoding_name_to_id_map_.reset(new CanonicalEncodingNameToIdMapType);
    for (int i = 0; i < kCanonicalEncodingNamesLength; ++i) {
      (*encoding_name_to_id_map_)[kCanonicalEncodingNames[i].name] =
          kCanonicalEncodingNames[i].resource_id;
    }
  }
  return encoding_name_to_id_map_.get();
}

const CanonicalNameDisplayNameMapType*
    CanonicalEncodingMap::GetCanonicalNameDisplayNameMapData() {
  if (!encoding_name_to_display_name_map_.get()) {
    encoding_name_to_display_name_map_.reset(
        new CanonicalNameDisplayNameMapType);
    // First store the names in the kCanonicalEncodingNames list.
    for (int i = 0; i < kCanonicalEncodingNamesLength; ++i) {
      (*encoding_name_to_display_name_map_)[kCanonicalEncodingNames[i].name] =
          kCanonicalEncodingNames[i].name;
    }
    // Then save in the overrides.
    for (int i = 0; i < kCanonicalDisplayNameOverridesLength; ++i) {
      (*encoding_name_to_display_name_map_)
          [kCanonicalDisplayNameOverrides[i].canonical_form] =
          kCanonicalDisplayNameOverrides[i].display_form;
    }
    DCHECK(static_cast<int>(encoding_name_to_display_name_map_->size()) ==
           kCanonicalEncodingNamesLength)
        << "Got an override that wasn't in the encoding list";
  }
  return encoding_name_to_display_name_map_.get();
}

// A static map object which contains all resourceid-nonsequenced canonical
// encoding names.
CanonicalEncodingMap* CanonicalEncodingMapSingleton() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  static CanonicalEncodingMap* singleton = new CanonicalEncodingMap;
  return singleton;
}

const int kDefaultEncodingMenus[] = {
  IDC_ENCODING_UTF16LE,
  IDC_ENCODING_WINDOWS1252,
  IDC_ENCODING_GBK,
  IDC_ENCODING_GB18030,
  IDC_ENCODING_BIG5,
  IDC_ENCODING_BIG5HKSCS,
  IDC_ENCODING_KOREAN,
  IDC_ENCODING_SHIFTJIS,
  IDC_ENCODING_EUCJP,
  IDC_ENCODING_ISO2022JP,
  IDC_ENCODING_THAI,
  IDC_ENCODING_ISO885915,
  IDC_ENCODING_MACINTOSH,
  IDC_ENCODING_ISO88592,
  IDC_ENCODING_WINDOWS1250,
  IDC_ENCODING_ISO88595,
  IDC_ENCODING_WINDOWS1251,
  IDC_ENCODING_KOI8R,
  IDC_ENCODING_KOI8U,
  IDC_ENCODING_ISO88597,
  IDC_ENCODING_WINDOWS1253,
  IDC_ENCODING_WINDOWS1254,
  IDC_ENCODING_WINDOWS1256,
  IDC_ENCODING_ISO88596,
  IDC_ENCODING_WINDOWS1255,
  IDC_ENCODING_ISO88598I,
  IDC_ENCODING_ISO88598,
  IDC_ENCODING_WINDOWS1258,
  IDC_ENCODING_ISO88594,
  IDC_ENCODING_ISO885913,
  IDC_ENCODING_WINDOWS1257,
  IDC_ENCODING_ISO88593,
  IDC_ENCODING_ISO885910,
  IDC_ENCODING_ISO885914,
  IDC_ENCODING_ISO885916,
};

const int kDefaultEncodingMenusLength = arraysize(kDefaultEncodingMenus);

// Parse the input |encoding_list| which is a encoding list separated with
// comma, get available encoding ids and save them to |available_list|.
// The parameter |maximum_size| indicates maximum size of encoding items we
// want to get from the |encoding_list|.
void ParseEncodingListSeparatedWithComma(
    const std::string& encoding_list, std::vector<int>* const available_list,
    size_t maximum_size) {
  base::StringTokenizer tokenizer(encoding_list, ",");
  while (tokenizer.GetNext()) {
    int id = CharacterEncoding::GetCommandIdByCanonicalEncodingName(
        tokenizer.token());
    // Ignore invalid encoding.
    if (!id)
      continue;
    available_list->push_back(id);
    if (available_list->size() == maximum_size)
      return;
  }
}

base::string16 GetEncodingDisplayName(const std::string& encoding_name,
                                      int category_string_id) {
  base::string16 category_name = l10n_util::GetStringUTF16(category_string_id);
  if (category_string_id != IDS_ENCODING_KOREAN &&
      category_string_id != IDS_ENCODING_THAI &&
      category_string_id != IDS_ENCODING_TURKISH &&
      category_string_id != IDS_ENCODING_VIETNAMESE &&
      category_string_id != IDS_ENCODING_ROMANIAN) {
    const CanonicalNameDisplayNameMapType* map =
        CanonicalEncodingMapSingleton()->GetCanonicalNameDisplayNameMapData();
    DCHECK(map);

    CanonicalNameDisplayNameMapType::const_iterator found_name =
        map->find(encoding_name);
    DCHECK(found_name != map->end());
    return l10n_util::GetStringFUTF16(IDS_ENCODING_DISPLAY_TEMPLATE,
                                      category_name,
                                      base::ASCIIToUTF16(found_name->second));
  }
  return category_name;
}

int GetEncodingCategoryStringIdByCommandId(int id) {
  const IdToCanonicalEncodingNameMapType* map =
      CanonicalEncodingMapSingleton()->GetIdToCanonicalEncodingNameMapData();
  DCHECK(map);

  IdToCanonicalEncodingNameMapType::const_iterator found_name = map->find(id);
  if (found_name != map->end())
    return found_name->second.second;
  return 0;
}

std::string GetEncodingCategoryStringByCommandId(int id) {
  int category_id = GetEncodingCategoryStringIdByCommandId(id);
  if (category_id)
    return l10n_util::GetStringUTF8(category_id);
  return std::string();
}

}  // namespace

CharacterEncoding::EncodingInfo::EncodingInfo(int id)
    : encoding_id(id) {
  encoding_category_name =
      base::UTF8ToUTF16(GetEncodingCategoryStringByCommandId(id));
  encoding_display_name = GetCanonicalEncodingDisplayNameByCommandId(id);
}

// Static.
int CharacterEncoding::GetCommandIdByCanonicalEncodingName(
    const std::string& encoding_name) {
  const CanonicalEncodingNameToIdMapType* map =
      CanonicalEncodingMapSingleton()->GetCanonicalEncodingNameToIdMapData();
  DCHECK(map);

  CanonicalEncodingNameToIdMapType::const_iterator found_id =
      map->find(encoding_name);
  if (found_id != map->end())
    return found_id->second;
  return 0;
}

// Static.
std::string CharacterEncoding::GetCanonicalEncodingNameByCommandId(int id) {
  const IdToCanonicalEncodingNameMapType* map =
      CanonicalEncodingMapSingleton()->GetIdToCanonicalEncodingNameMapData();
  DCHECK(map);

  IdToCanonicalEncodingNameMapType::const_iterator found_name = map->find(id);
  if (found_name != map->end())
    return found_name->second.first;
  return std::string();
}

// Static.
base::string16 CharacterEncoding::GetCanonicalEncodingDisplayNameByCommandId(
    int id) {
  const IdToCanonicalEncodingNameMapType* map =
      CanonicalEncodingMapSingleton()->GetIdToCanonicalEncodingNameMapData();
  DCHECK(map);

  IdToCanonicalEncodingNameMapType::const_iterator found_name = map->find(id);
  if (found_name != map->end())
    return GetEncodingDisplayName(found_name->second.first,
                                  found_name->second.second);
  return base::string16();
}

// Static.
// Return count number of all supported canonical encoding.
int CharacterEncoding::GetSupportCanonicalEncodingCount() {
  return kCanonicalEncodingNamesLength;
}

// Static.
std::string CharacterEncoding::GetCanonicalEncodingNameByIndex(int index) {
  if (index < kCanonicalEncodingNamesLength)
    return kCanonicalEncodingNames[index].name;
  return std::string();
}

// Static.
base::string16 CharacterEncoding::GetCanonicalEncodingDisplayNameByIndex(
    int index) {
  if (index < kCanonicalEncodingNamesLength)
    return GetEncodingDisplayName(kCanonicalEncodingNames[index].name,
        kCanonicalEncodingNames[index].category_string_id);
  return base::string16();
}

// Static.
int CharacterEncoding::GetEncodingCommandIdByIndex(int index) {
  if (index < kCanonicalEncodingNamesLength)
    return kCanonicalEncodingNames[index].resource_id;
  return 0;
}

// Static.
std::string CharacterEncoding::GetCanonicalEncodingNameByAliasName(
    const std::string& alias_name) {
  // If the input alias_name is already canonical encoding name, just return it.
  const CanonicalEncodingNameToIdMapType* map =
      CanonicalEncodingMapSingleton()->GetCanonicalEncodingNameToIdMapData();
  DCHECK(map);

  CanonicalEncodingNameToIdMapType::const_iterator found_id =
      map->find(alias_name);
  if (found_id != map->end())
    return alias_name;

  const char* standards[3] = { "HTML", "MIME", "IANA" };
  for (size_t i = 0; i < arraysize(standards); ++i) {
    UErrorCode error_code = U_ZERO_ERROR;
    const char* canonical_name = ucnv_getCanonicalName(
        alias_name.c_str(), standards[i], &error_code);
    if (U_SUCCESS(error_code) && canonical_name)
      return canonical_name;
  }
  return std::string();
}

// Static
// According to the behavior of user recently selected encoding short list in
// Firefox, we always put UTF-8 as top position, after then put user
// recent selected encodings, then put local dependent encoding items.
// At last, we put all remaining encoding items.
const std::vector<CharacterEncoding::EncodingInfo>*
    CharacterEncoding::GetCurrentDisplayEncodings(
    const std::string& locale,
    const std::string& locale_encodings,
    const std::string& recently_select_encodings) {
  std::vector<int>* const locale_dependent_encoding_list =
      CanonicalEncodingMapSingleton()->locale_dependent_encoding_ids();
  std::vector<CharacterEncoding::EncodingInfo>* const encoding_list =
      CanonicalEncodingMapSingleton()->current_display_encodings();

  // Initialize locale dependent static encoding list.
  if (locale_dependent_encoding_list->empty() && !locale_encodings.empty())
    ParseEncodingListSeparatedWithComma(locale_encodings,
                                        locale_dependent_encoding_list,
                                        kUserSelectedEncodingsMaxLength);

  CR_DEFINE_STATIC_LOCAL(std::string, cached_user_selected_encodings, ());
  // Build current display encoding list.
  if (encoding_list->empty() ||
      cached_user_selected_encodings != recently_select_encodings) {
    // Update user recently selected encodings.
    cached_user_selected_encodings = recently_select_encodings;
    // Clear old encoding list since user recently selected encodings changed.
    encoding_list->clear();
    // Always add UTF-8 to first encoding position.
    encoding_list->push_back(EncodingInfo(IDC_ENCODING_UTF8));
    std::set<int> inserted_encoding;
    inserted_encoding.insert(IDC_ENCODING_UTF8);

    // Parse user recently selected encodings and get list
    std::vector<int> recently_select_encoding_list;
    ParseEncodingListSeparatedWithComma(recently_select_encodings,
                                        &recently_select_encoding_list,
                                        kUserSelectedEncodingsMaxLength);

    // Put 'cached encodings' (dynamic encoding list) after 'local dependent
    // encoding list'.
    recently_select_encoding_list.insert(recently_select_encoding_list.begin(),
        locale_dependent_encoding_list->begin(),
        locale_dependent_encoding_list->end());
    for (std::vector<int>::iterator it = recently_select_encoding_list.begin();
         it != recently_select_encoding_list.end(); ++it) {
        // Test whether we have met this encoding id.
        bool ok = inserted_encoding.insert(*it).second;
        // Duplicated encoding, ignore it. Ideally, this situation should not
        // happened, but just in case some one manually edit preference file.
        if (!ok)
          continue;
        encoding_list->push_back(EncodingInfo(*it));
    }
    // Append a separator;
    encoding_list->push_back(EncodingInfo(0));

    // We need to keep "Unicode (UTF-16LE)" always at the top (among the rest
    // of encodings) instead of being sorted along with other encodings. So if
    // "Unicode (UTF-16LE)" is already in previous encodings, sort the rest
    // of encodings. Otherwise Put "Unicode (UTF-16LE)" on the first of the
    // rest of encodings, skip "Unicode (UTF-16LE)" and sort all left encodings.
    int start_sorted_index = encoding_list->size();
    if (inserted_encoding.find(IDC_ENCODING_UTF16LE) ==
        inserted_encoding.end()) {
      encoding_list->push_back(EncodingInfo(IDC_ENCODING_UTF16LE));
      inserted_encoding.insert(IDC_ENCODING_UTF16LE);
      start_sorted_index++;
    }

    // Add the rest of encodings that are neither in the static encoding list
    // nor in the list of recently selected encodings.
    // Build the encoding list sorted in the current locale sorting order.
    for (int i = 0; i < kDefaultEncodingMenusLength; ++i) {
      int id = kDefaultEncodingMenus[i];
      // We have inserted this encoding, skip it.
      if (inserted_encoding.find(id) != inserted_encoding.end())
        continue;
      encoding_list->push_back(EncodingInfo(id));
    }
    // Sort the encoding list.
    l10n_util::SortVectorWithStringKey(locale,
                                       encoding_list,
                                       start_sorted_index,
                                       encoding_list->size(),
                                       true);
  }
  DCHECK(!encoding_list->empty());
  return encoding_list;
}

// Static
bool CharacterEncoding::UpdateRecentlySelectedEncoding(
    const std::string& original_selected_encodings,
    int new_selected_encoding_id,
    std::string* selected_encodings) {
  // Get encoding name.
  std::string encoding_name =
      GetCanonicalEncodingNameByCommandId(new_selected_encoding_id);
  DCHECK(!encoding_name.empty());
  // Check whether the new encoding is in local dependent encodings or original
  // recently selected encodings. If yes, do not add it.
  std::vector<int>* locale_dependent_encoding_list =
      CanonicalEncodingMapSingleton()->locale_dependent_encoding_ids();
  DCHECK(locale_dependent_encoding_list);
  std::vector<int> selected_encoding_list;
  ParseEncodingListSeparatedWithComma(original_selected_encodings,
                                      &selected_encoding_list,
                                      kUserSelectedEncodingsMaxLength);
  // Put 'cached encodings' (dynamic encoding list) after 'local dependent
  // encoding list' for check.
  std::vector<int> top_encoding_list(*locale_dependent_encoding_list);
  // UTF8 is always in our optimized encoding list.
  top_encoding_list.insert(top_encoding_list.begin(), IDC_ENCODING_UTF8);
  top_encoding_list.insert(top_encoding_list.end(),
                           selected_encoding_list.begin(),
                           selected_encoding_list.end());
  for (std::vector<int>::const_iterator it = top_encoding_list.begin();
       it != top_encoding_list.end(); ++it)
    if (*it == new_selected_encoding_id)
      return false;
  // Need to add the encoding id to recently selected encoding list.
  // Remove the last encoding in original list.
  if (selected_encoding_list.size() == kUserSelectedEncodingsMaxLength)
    selected_encoding_list.pop_back();
  // Insert new encoding to head of selected encoding list.
  *selected_encodings = encoding_name;
  // Generate the string for rest selected encoding list.
  for (std::vector<int>::const_iterator it = selected_encoding_list.begin();
       it != selected_encoding_list.end(); ++it) {
    selected_encodings->append(1, L',');
    selected_encodings->append(GetCanonicalEncodingNameByCommandId(*it));
  }
  return true;
}
