// Copyright 2017 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.

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_STRING_RESOURCE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_STRING_RESOURCE_H_

#include "base/macros.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/threading.h"
#include "v8/include/v8.h"

namespace blink {

// StringResource is a helper class for V8ExternalString. It is used
// to manage the life-cycle of the underlying buffer of the external string.
class StringResourceBase {
  USING_FAST_MALLOC(StringResourceBase);

 public:
  explicit StringResourceBase(const String& string) : plain_string_(string) {
#if DCHECK_IS_ON()
    thread_id_ = WTF::CurrentThread();
#endif
    DCHECK(!string.IsNull());
    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
        string.CharactersSizeInBytes());
  }

  explicit StringResourceBase(const AtomicString& string)
      : plain_string_(string.GetString()), atomic_string_(string) {
#if DCHECK_IS_ON()
    thread_id_ = WTF::CurrentThread();
#endif
    DCHECK(!string.IsNull());
    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
        string.CharactersSizeInBytes());
  }

  explicit StringResourceBase(const ParkableString& string)
      : parkable_string_(string) {
#if DCHECK_IS_ON()
    thread_id_ = WTF::CurrentThread();
#endif
    // TODO(lizeb): This is only true without compression.
    DCHECK(!string.IsNull());
    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
        string.CharactersSizeInBytes());
  }

  virtual ~StringResourceBase() {
#if DCHECK_IS_ON()
    DCHECK(thread_id_ == WTF::CurrentThread());
#endif
    int64_t reduced_external_memory = plain_string_.CharactersSizeInBytes();
    if (plain_string_.Impl() != atomic_string_.Impl() &&
        !atomic_string_.IsNull())
      reduced_external_memory += atomic_string_.CharactersSizeInBytes();
    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
        -reduced_external_memory);
  }

  String GetWTFString() {
    if (!parkable_string_.IsNull()) {
      DCHECK(plain_string_.IsNull());
      DCHECK(atomic_string_.IsNull());
      return parkable_string_.ToString();
    }
    return plain_string_;
  }

  AtomicString GetAtomicString() {
#if DCHECK_IS_ON()
    DCHECK(thread_id_ == WTF::CurrentThread());
#endif
    if (!parkable_string_.IsNull()) {
      DCHECK(plain_string_.IsNull());
      DCHECK(atomic_string_.IsNull());
      return AtomicString(parkable_string_.ToString());
    }
    if (atomic_string_.IsNull()) {
      atomic_string_ = AtomicString(plain_string_);
      DCHECK(!atomic_string_.IsNull());
      if (plain_string_.Impl() != atomic_string_.Impl()) {
        v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(
            atomic_string_.CharactersSizeInBytes());
      }
    }
    return atomic_string_;
  }

 protected:
  // A shallow copy of the string. Keeps the string buffer alive until the V8
  // engine garbage collects it.
  String plain_string_;
  // If this string is atomic or has been made atomic earlier the
  // atomic string is held here. In the case where the string starts
  // off non-atomic and becomes atomic later it is necessary to keep
  // the original string alive because v8 may keep derived pointers
  // into that string.
  AtomicString atomic_string_;
  // If this string is parkable, its value is held here, and the other
  // members above are null.
  ParkableString parkable_string_;

 private:
#if DCHECK_IS_ON()
  WTF::ThreadIdentifier thread_id_;
#endif

  DISALLOW_COPY_AND_ASSIGN(StringResourceBase);
};

class StringResource16 final : public StringResourceBase,
                               public v8::String::ExternalStringResource {
 public:
  explicit StringResource16(const String& string) : StringResourceBase(string) {
    DCHECK(!string.Is8Bit());
  }

  explicit StringResource16(const AtomicString& string)
      : StringResourceBase(string) {
    DCHECK(!string.Is8Bit());
  }

  size_t length() const override { return plain_string_.Impl()->length(); }
  const uint16_t* data() const override {
    return reinterpret_cast<const uint16_t*>(
        plain_string_.Impl()->Characters16());
  }

  DISALLOW_COPY_AND_ASSIGN(StringResource16);
};

class StringResource8 final : public StringResourceBase,
                              public v8::String::ExternalOneByteStringResource {
 public:
  explicit StringResource8(const String& string) : StringResourceBase(string) {
    DCHECK(string.Is8Bit());
  }

  explicit StringResource8(const AtomicString& string)
      : StringResourceBase(string) {
    DCHECK(string.Is8Bit());
  }

  size_t length() const override { return plain_string_.Impl()->length(); }
  const char* data() const override {
    return reinterpret_cast<const char*>(plain_string_.Impl()->Characters8());
  }

  DISALLOW_COPY_AND_ASSIGN(StringResource8);
};

class ParkableStringResource16 final
    : public StringResourceBase,
      public v8::String::ExternalStringResource {
 public:
  explicit ParkableStringResource16(const ParkableString& string)
      : StringResourceBase(string) {
    DCHECK(!parkable_string_.Is8Bit());
  }

  bool IsCacheable() const override {
    return !parkable_string_.may_be_parked();
  }

  void Lock() const override { parkable_string_.Lock(); }

  void Unlock() const override { parkable_string_.Unlock(); }

  size_t length() const override { return parkable_string_.length(); }

  const uint16_t* data() const override {
    return reinterpret_cast<const uint16_t*>(parkable_string_.Characters16());
  }

  DISALLOW_COPY_AND_ASSIGN(ParkableStringResource16);
};

class ParkableStringResource8 final
    : public StringResourceBase,
      public v8::String::ExternalOneByteStringResource {
 public:
  explicit ParkableStringResource8(const ParkableString& string)
      : StringResourceBase(string) {
    DCHECK(parkable_string_.Is8Bit());
  }

  bool IsCacheable() const override {
    return !parkable_string_.may_be_parked();
  }

  void Lock() const override { parkable_string_.Lock(); }

  void Unlock() const override { parkable_string_.Unlock(); }

  size_t length() const override { return parkable_string_.length(); }

  const char* data() const override {
    return reinterpret_cast<const char*>(parkable_string_.Characters8());
  }

  DISALLOW_COPY_AND_ASSIGN(ParkableStringResource8);
};

enum ExternalMode { kExternalize, kDoNotExternalize };

template <typename StringType>
PLATFORM_EXPORT StringType ToBlinkString(v8::Local<v8::String>, ExternalMode);
PLATFORM_EXPORT String ToBlinkString(int value);

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_STRING_RESOURCE_H_
