// Copyright 2016 Google Inc. 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 <algorithm>

#include "cobalt/dom/blob.h"
#include "cobalt/dom/dom_settings.h"
#include "cobalt/dom/testing/stub_window.h"
#include "cobalt/script/data_view.h"
#include "cobalt/script/testing/mock_exception_state.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace dom {
namespace {

using script::testing::MockExceptionState;
using ::testing::_;
using ::testing::SaveArg;
using ::testing::StrictMock;

TEST(BlobTest, Constructors) {
  // Initialize JavaScriptEngine and its environment.
  testing::StubWindow stub_window;
  script::GlobalEnvironment* global_environment =
      stub_window.global_environment();
  script::EnvironmentSettings* environment_settings =
      stub_window.environment_settings();

  script::Handle<script::ArrayBuffer> array_buffer =
      script::ArrayBuffer::New(global_environment, 5);
  scoped_refptr<Blob> blob_default_buffer = new Blob(environment_settings);

  EXPECT_EQ(0, blob_default_buffer->size());

  script::Handle<script::DataView> data_view = script::DataView::New(
      global_environment, array_buffer, 0, array_buffer->ByteLength());
  uint8 test_data[] = {0x06, 0x07, 0x00, 0x7B, 0xCD};
  SbMemoryCopy(data_view->RawData(), test_data, 5);
  scoped_refptr<Blob> blob_with_buffer =
      new Blob(environment_settings, array_buffer);

  ASSERT_EQ(5, blob_with_buffer->size());
  ASSERT_TRUE(blob_with_buffer->data());

  EXPECT_EQ(0x6, blob_with_buffer->data()[0]);
  EXPECT_EQ(0x7, blob_with_buffer->data()[1]);
  EXPECT_EQ(0, blob_with_buffer->data()[2]);
  EXPECT_EQ(0x7B, blob_with_buffer->data()[3]);
  EXPECT_EQ(0xCD, blob_with_buffer->data()[4]);

  script::Handle<script::DataView> data_view_mid_3 =
      script::DataView::New(global_environment, array_buffer, 1, 3);
  script::Sequence<Blob::BlobPart> parts;
  parts.push_back(Blob::BlobPart(blob_with_buffer));
  parts.push_back(Blob::BlobPart(data_view_mid_3));
  parts.push_back(Blob::BlobPart(array_buffer));
  scoped_refptr<Blob> blob_with_parts = new Blob(environment_settings, parts);

  ASSERT_EQ(13UL, blob_with_parts->size());
  ASSERT_TRUE(blob_with_parts->data());
  EXPECT_EQ(0x6, blob_with_parts->data()[0]);
  EXPECT_EQ(0x7, blob_with_parts->data()[5]);
  EXPECT_EQ(0, blob_with_parts->data()[6]);
  EXPECT_EQ(0x7B, blob_with_parts->data()[11]);
  EXPECT_EQ(0xCD, blob_with_parts->data()[12]);
}

// Tests that further changes to a buffer from which a blob was constructed
// no longer affect the blob's buffer, since it must be a separate copy of
// its construction arguments.

TEST(BlobTest, HasOwnBuffer) {
  // Initialize JavaScriptEngine and its environment.
  testing::StubWindow stub_window;
  script::GlobalEnvironment* global_environment =
      stub_window.global_environment();
  script::EnvironmentSettings* environment_settings =
      stub_window.environment_settings();
  StrictMock<MockExceptionState> exception_state;

  script::Handle<script::ArrayBuffer> array_buffer =
      script::ArrayBuffer::New(global_environment, 2);
  script::Handle<script::DataView> data_view = script::DataView::New(
      global_environment, array_buffer, 0, array_buffer->ByteLength());

  uint8 test_data[2] = {0x06, 0x07};
  SbMemoryCopy(data_view->RawData(), test_data, 2);

  scoped_refptr<Blob> blob_with_buffer =
      new Blob(environment_settings, array_buffer);

  ASSERT_EQ(2, blob_with_buffer->size());
  ASSERT_TRUE(blob_with_buffer->data());
  EXPECT_NE(array_buffer->Data(), blob_with_buffer->data());

  uint8 test_data2[1] = {0xff};
  memcpy(data_view->RawData(), test_data2, 1);

  EXPECT_EQ(0x6, blob_with_buffer->data()[0]);
  EXPECT_EQ(0x7, blob_with_buffer->data()[1]);
}

}  // namespace
}  // namespace dom
}  // namespace cobalt
