// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_INTL_SUPPORT
#error Internationalization is expected to be enabled.
#endif  // V8_INTL_SUPPORT

#include "src/objects/js-segment-iterator.h"

#include <map>
#include <memory>
#include <string>

#include "src/execution/isolate.h"
#include "src/heap/factory.h"
#include "src/objects/intl-objects.h"
#include "src/objects/js-segment-iterator-inl.h"
#include "src/objects/js-segments.h"
#include "src/objects/managed.h"
#include "src/objects/objects-inl.h"
#include "unicode/brkiter.h"

namespace v8 {
namespace internal {

Handle<String> JSSegmentIterator::GranularityAsString(Isolate* isolate) const {
  return JSSegmenter::GetGranularityString(isolate, granularity());
}

// ecma402 #sec-createsegmentiterator
MaybeHandle<JSSegmentIterator> JSSegmentIterator::Create(
    Isolate* isolate, icu::BreakIterator* break_iterator,
    JSSegmenter::Granularity granularity) {
  // Clone a copy for both the ownership and not sharing with containing and
  // other calls to the iterator because icu::BreakIterator keep the iteration
  // position internally and cannot be shared across multiple calls to
  // JSSegmentIterator::Create and JSSegments::Containing.
  break_iterator = break_iterator->clone();
  DCHECK_NOT_NULL(break_iterator);
  Handle<Map> map = Handle<Map>(
      isolate->native_context()->intl_segment_iterator_map(), isolate);

  // 5. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to 0.
  break_iterator->first();
  Handle<Managed<icu::BreakIterator>> managed_break_iterator =
      Managed<icu::BreakIterator>::FromRawPtr(isolate, 0, break_iterator);

  icu::UnicodeString* string = new icu::UnicodeString();
  break_iterator->getText().getText(*string);
  Handle<Managed<icu::UnicodeString>> unicode_string =
      Managed<icu::UnicodeString>::FromRawPtr(isolate, 0, string);

  break_iterator->setText(*string);

  // Now all properties are ready, so we can allocate the result object.
  Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(map);
  DisallowHeapAllocation no_gc;
  Handle<JSSegmentIterator> segment_iterator =
      Handle<JSSegmentIterator>::cast(result);

  segment_iterator->set_flags(0);
  segment_iterator->set_granularity(granularity);
  segment_iterator->set_icu_break_iterator(*managed_break_iterator);
  segment_iterator->set_unicode_string(*unicode_string);

  return segment_iterator;
}

// ecma402 #sec-%segmentiteratorprototype%.next
MaybeHandle<JSReceiver> JSSegmentIterator::Next(
    Isolate* isolate, Handle<JSSegmentIterator> segment_iterator) {
  Factory* factory = isolate->factory();
  icu::BreakIterator* icu_break_iterator =
      segment_iterator->icu_break_iterator().raw();
  // 5. Let startIndex be iterator.[[IteratedStringNextSegmentCodeUnitIndex]].
  int32_t start_index = icu_break_iterator->current();
  // 6. Let endIndex be ! FindBoundary(segmenter, string, startIndex, after).
  int32_t end_index = icu_break_iterator->next();

  // 7. If endIndex is not finite, then
  if (end_index == icu::BreakIterator::DONE) {
    // a. Return ! CreateIterResultObject(undefined, true).
    return factory->NewJSIteratorResult(isolate->factory()->undefined_value(),
                                        true);
  }

  // 8. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to endIndex.

  // 9. Let segmentData be ! CreateSegmentDataObject(segmenter, string,
  // startIndex, endIndex).

  icu::UnicodeString string;
  icu_break_iterator->getText().getText(string);

  Handle<Object> segment_data;
  ASSIGN_RETURN_ON_EXCEPTION(
      isolate, segment_data,
      JSSegments::CreateSegmentDataObject(
          isolate, segment_iterator->granularity(), icu_break_iterator, string,
          start_index, end_index),
      JSReceiver);

  // 10. Return ! CreateIterResultObject(segmentData, false).
  return factory->NewJSIteratorResult(segment_data, false);
}

}  // namespace internal
}  // namespace v8
