// Copyright 2013 The Flutter 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 "flutter/fml/icu_util.h"

#include <memory>
#include <mutex>

#include "flutter/fml/build_config.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/mapping.h"
#include "flutter/fml/native_library.h"
#include "flutter/fml/paths.h"
#include "third_party/icu/source/common/unicode/udata.h"

namespace fml {
namespace icu {

class ICUContext {
 public:
  ICUContext(const std::string& icu_data_path) : valid_(false) {
    valid_ = SetupMapping(icu_data_path) && SetupICU();
  }

  ICUContext(std::unique_ptr<Mapping> mapping) : mapping_(std::move(mapping)) {
    valid_ = SetupICU();
  }

  ~ICUContext() = default;

  bool SetupMapping(const std::string& icu_data_path) {
    // Check if the path exists and it readable directly.
    auto fd =
        fml::OpenFile(icu_data_path.c_str(), false, fml::FilePermission::kRead);

    // Check the path relative to the current executable.
    if (!fd.is_valid()) {
      auto directory = fml::paths::GetExecutableDirectoryPath();

      if (!directory.first) {
        return false;
      }

      std::string path_relative_to_executable =
          paths::JoinPaths({directory.second, icu_data_path});

      fd = fml::OpenFile(path_relative_to_executable.c_str(), false,
                         fml::FilePermission::kRead);
    }

    if (!fd.is_valid()) {
      return false;
    }

    std::initializer_list<FileMapping::Protection> protection = {
        fml::FileMapping::Protection::kRead};

    auto file_mapping =
        std::make_unique<FileMapping>(fd, std::move(protection));

    if (file_mapping->GetSize() != 0) {
      mapping_ = std::move(file_mapping);
      return true;
    }

    return false;
  }

  bool SetupICU() {
    if (GetSize() == 0) {
      return false;
    }

    UErrorCode err_code = U_ZERO_ERROR;
    udata_setCommonData(GetMapping(), &err_code);
    return (err_code == U_ZERO_ERROR);
  }

  const uint8_t* GetMapping() const {
    return mapping_ ? mapping_->GetMapping() : nullptr;
  }

  size_t GetSize() const { return mapping_ ? mapping_->GetSize() : 0; }

  bool IsValid() const { return valid_; }

 private:
  bool valid_;
  std::unique_ptr<Mapping> mapping_;

  FML_DISALLOW_COPY_AND_ASSIGN(ICUContext);
};

void InitializeICUOnce(const std::string& icu_data_path) {
  static ICUContext* context = new ICUContext(icu_data_path);
  FML_CHECK(context->IsValid())
      << "Must be able to initialize the ICU context. Tried: " << icu_data_path;
}

std::once_flag g_icu_init_flag;
void InitializeICU(const std::string& icu_data_path) {
  std::call_once(g_icu_init_flag,
                 [&icu_data_path]() { InitializeICUOnce(icu_data_path); });
}

void InitializeICUFromMappingOnce(std::unique_ptr<Mapping> mapping) {
  static ICUContext* context = new ICUContext(std::move(mapping));
  FML_CHECK(context->IsValid())
      << "Unable to initialize the ICU context from a mapping.";
}

void InitializeICUFromMapping(std::unique_ptr<Mapping> mapping) {
  std::call_once(g_icu_init_flag, [mapping = std::move(mapping)]() mutable {
    InitializeICUFromMappingOnce(std::move(mapping));
  });
}

}  // namespace icu
}  // namespace fml
