// Copyright 2021 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/encoding/text_decoder.h"

#include <algorithm>
#include <cctype>

#include "third_party/icu/source/common/unicode/uchriter.h"
#include "third_party/icu/source/common/unicode/ucnv.h"
#include "third_party/icu/source/common/unicode/unistr.h"
#include "third_party/icu/source/common/unicode/utypes.h"

namespace cobalt {
namespace encoding {

// static
const std::size_t TextDecoder::kConversionBufferSize = 16384;  // 2^14
const TextDecoderOptions TextDecoder::kDefaultDecoderOptions;
const char TextDecoder::kDefaultEncoding[] = "utf-8";
const UChar32 TextDecoder::kReplacementCharacter = 0xFFFD;
const char TextDecoder::kReplacementEncoding[] = "REPLACEMENT";


namespace {
std::string ToLower(std::string str) {
  std::transform(str.begin(), str.end(), str.begin(),
                 [](unsigned char c) { return std::tolower(c); });
  return str;
}
}  // namespace

void TextDecoder::Cleanup() {
  encoding_.clear();
  if (converter_) {
    ucnv_close(converter_);
  }
  converter_ = nullptr;
}

void TextDecoder::Setup(std::string label,
                        script::ExceptionState* exception_state,
                        const TextDecoderOptions& options) {
  // "utf-16" is a label for UTF-16LE to deal with deployed content.
  //  https://encoding.spec.whatwg.org/#utf-16le
  if (label == "utf-16") {
    label = "utf-16le";
  }
  UErrorCode error_code = U_ZERO_ERROR;
  converter_ = ucnv_open(label.c_str(), &error_code);
  if (U_FAILURE(error_code)) {
    LOG(ERROR) << "Unable to open converter. " << u_errorName(error_code);
    exception_state->SetSimpleException(script::kRangeError,
                                        "label %s is invalid", label.c_str());
    return Cleanup();
  }

  error_code = U_ZERO_ERROR;
  encoding_ = ucnv_getName(converter_, &error_code);
  if (U_FAILURE(error_code) || encoding_ == kReplacementEncoding) {
    LOG(ERROR) << "Unable to get encoding name. " << u_errorName(error_code);
    exception_state->SetSimpleException(
        script::kRangeError, "encoding %s is invalid", encoding_.c_str());
    return Cleanup();
  }

  // Internal default setup;
  encoding_ = ToLower(encoding_);
  error_mode_ = options.fatal() ? "fatal" : "replacement";
  ignore_bom_ = options.ignore_bom();
  bom_seen_ = false;
  do_not_flush_ = false;
}

TextDecoder::TextDecoder(script::ExceptionState* exception_state)
    : converter_(nullptr) {
  Setup(kDefaultEncoding, exception_state, kDefaultDecoderOptions);
}

TextDecoder::TextDecoder(const std::string& label,
                         script::ExceptionState* exception_state)
    : converter_(nullptr) {
  Setup(label, exception_state, kDefaultDecoderOptions);
}

TextDecoder::TextDecoder(const TextDecoderOptions& options,
                         script::ExceptionState* exception_state) {
  Setup(kDefaultEncoding, exception_state, options);
}

TextDecoder::TextDecoder(const std::string& label,
                         const TextDecoderOptions& options,
                         script::ExceptionState* exception_state) {
  Setup(label, exception_state, options);
}

TextDecoder::~TextDecoder() { Cleanup(); }

std::string TextDecoder::Decode(script::ExceptionState* exception_state) {
  const TextDecodeOptions default_options;
  return Decode(default_options, exception_state);
}

std::string TextDecoder::Decode(const web::BufferSource& input,
                                script::ExceptionState* exception_state) {
  const TextDecodeOptions default_options;
  return Decode(input, default_options, exception_state);
}

std::string TextDecoder::Decode(const TextDecodeOptions& options,
                                script::ExceptionState* exception_state) {
  std::string result;
  Decode(nullptr, 0, options, exception_state, &result);
  return result;
}

std::string TextDecoder::Decode(const web::BufferSource& input,
                                const TextDecodeOptions& options,
                                script::ExceptionState* exception_state) {
  int32_t size;
  const uint8* buffer;
  std::string result;
  web::GetBufferAndSize(input, &buffer, &size);
  Decode(reinterpret_cast<const char*>(buffer), size, options, exception_state,
         &result);
  return result;
}

// General Decode method, all public methods end here.
void TextDecoder::Decode(const char* start, int32_t length,
                         const TextDecodeOptions& options,
                         script::ExceptionState* exception_state,
                         std::string* output) {
  if (!converter_) {
    return;
  }
  if (!do_not_flush_) {
    bom_seen_ = false;
  }
  if (!ignore_bom_ && !bom_seen_ && length) {
    bom_seen_ = true;
    if (!RemoveBOM(start, length, exception_state)) {
      return;
    }
  }
  do_not_flush_ = options.stream();
  bool saw_error = false;
  DecodeImpl(start, length, !do_not_flush_, error_mode_ == "fatal", saw_error,
             output);

  if (error_mode_ == "fatal" && saw_error) {
    if (!do_not_flush_) {
      // If flushing, the error should not persist.
      ucnv_reset(converter_);
    }
    exception_state->SetSimpleException(script::kTypeError,
                                        "Error processing the encoded data");
  }
  return;
}

bool TextDecoder::RemoveBOM(const char*& buffer, int& size,
                            script::ExceptionState* exception_state) {
  UErrorCode error_code = U_ZERO_ERROR;
  int32_t signature_length = 0;
  const char* detected_encoding =
      ucnv_detectUnicodeSignature(buffer, size, &signature_length, &error_code);
  if (U_FAILURE(error_code)) {
    LOG(ERROR) << "Error detecting signature " << u_errorName(error_code);
    exception_state->SetSimpleException(script::kRangeError,
                                        "Error detecting signature");
    return false;
  }

  // Only remove BOM when both encodings match.
  if (detected_encoding && (ToLower(detected_encoding) == encoding_)) {
    buffer += signature_length;
    size -= signature_length;
    LOG(INFO) << "Buffer adjusted (+" << signature_length << ") bytes.";
  }
  return true;
}

class ErrorCallbackSetter final {
 public:
  ErrorCallbackSetter(UConverter* converter, bool stop_on_error)
      : converter_(converter), stop_on_error_(stop_on_error) {
    if (stop_on_error_) {
      UErrorCode error = U_ZERO_ERROR;
      ucnv_setToUCallBack(converter_, UCNV_TO_U_CALLBACK_STOP, nullptr,
                          &saved_action_, &saved_context_, &error);
      DCHECK_EQ(error, U_ZERO_ERROR);
    }
  }
  ~ErrorCallbackSetter() {
    if (stop_on_error_) {
      UErrorCode error = U_ZERO_ERROR;
      const void* old_context;
      UConverterToUCallback old_action;
      ucnv_setToUCallBack(converter_, saved_action_, saved_context_,
                          &old_action, &old_context, &error);
      DCHECK_EQ(old_action, UCNV_TO_U_CALLBACK_STOP);
      DCHECK(!old_context);
      DCHECK_EQ(error, U_ZERO_ERROR);
    }
  }

 private:
  UConverter* converter_;
  bool stop_on_error_;
  const void* saved_context_;
  UConverterToUCallback saved_action_;
};

namespace {
int DecodeTo(UConverter* converter_, UChar* target, UChar* target_limit,
             const char*& source, const char* source_limit, int32_t* offsets,
             bool flush, UErrorCode& error) {
  UChar* target_start = target;
  error = U_ZERO_ERROR;
  ucnv_toUnicode(converter_, &target, target_limit, &source, source_limit,
                 offsets, flush, &error);
  return static_cast<int>(target - target_start);
}
}  // namespace

void TextDecoder::DecodeImpl(const char* bytes, int length, bool flush,
                             bool stop_on_error, bool& saw_error,
                             std::string* output) {
  if (!converter_) {
    LOG(WARNING) << "no converter available.";
    return;
  }

  ErrorCallbackSetter callback_setter(converter_, stop_on_error);

  icu::UnicodeString result;

  UChar buffer[kConversionBufferSize];
  UChar* buffer_limit = buffer + kConversionBufferSize;
  const char* source = reinterpret_cast<const char*>(bytes);
  const char* source_limit = source + length;
  int32_t* offsets = nullptr;
  UErrorCode error = U_ZERO_ERROR;

  do {
    int uchars_decoded = DecodeTo(converter_, buffer, buffer_limit, source,
                                  source_limit, offsets, flush, error);
    result.append(buffer, uchars_decoded);
  } while (error == U_BUFFER_OVERFLOW_ERROR);

  // Flush the converter so it can be reused.
  if (U_FAILURE(error)) {
    do {
      DecodeTo(converter_, buffer, buffer_limit, source, source_limit, offsets,
               true, error);
    } while (source < source_limit);
    saw_error = true;
  }
  result.toUTF8String(*output);
  return;
}

}  // namespace encoding
}  // namespace cobalt
