// Copyright (c) 2011 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.

#include "gtest/gtest.h"

#include "base/memory/ref_counted.h"
#include "base/win/scoped_comptr.h"
#include "chrome_frame/urlmon_upload_data_stream.h"

TEST(UrlmonUploadDataStreamTest, TestBasicRead) {
  char random_string[] = "some random data, no really this totally random";
  int random_string_length = strlen(random_string);
  scoped_refptr<net::UploadData> upload_data = new net::UploadData();
  upload_data->AppendBytes(random_string, random_string_length);

  CComObject<UrlmonUploadDataStream>* upload_stream = NULL;
  HRESULT hr =
      CComObject<UrlmonUploadDataStream>::CreateInstance(&upload_stream);
  ASSERT_TRUE(SUCCEEDED(hr));

  upload_stream->Initialize(upload_data.get());
  base::win::ScopedComPtr<IStream> upload_istream(upload_stream);

  char buffer[500];
  memset(buffer, 0, 500);
  ULONG bytes_read = 0;
  hr = upload_istream->Read(buffer, 500, &bytes_read);

  EXPECT_TRUE(SUCCEEDED(hr));
  EXPECT_EQ(bytes_read, random_string_length);
  EXPECT_TRUE(strcmp(buffer, random_string) == 0);

  char buffer2[500];
  memset(buffer2, 0, 500);
  ULONG bytes_read2 = 0;
  hr = upload_istream->Read(buffer2, 500, &bytes_read2);

  EXPECT_EQ(S_FALSE, hr);
  EXPECT_EQ(bytes_read2, 0);
  EXPECT_FALSE(strcmp(buffer2, random_string) == 0);
}

TEST(UrlmonUploadDataStreamTest, TestBigRead) {
  const size_t kBigBufferLength = 100000;
  char big_buffer[kBigBufferLength];
  memset(big_buffer, 'a', kBigBufferLength);

  scoped_refptr<net::UploadData> upload_data = new net::UploadData();
  upload_data->AppendBytes(big_buffer, kBigBufferLength);

  CComObject<UrlmonUploadDataStream>* upload_stream = NULL;
  HRESULT hr =
      CComObject<UrlmonUploadDataStream>::CreateInstance(&upload_stream);
  ASSERT_TRUE(SUCCEEDED(hr));

  upload_stream->Initialize(upload_data.get());
  base::win::ScopedComPtr<IStream> upload_istream(upload_stream);

  char big_rcv_buffer[kBigBufferLength];
  int write_pos = 0;
  ULONG bytes_read = 0;
  hr = E_UNEXPECTED;

  while ((hr = upload_istream->Read(&big_rcv_buffer[write_pos],
                                    kBigBufferLength,
                                    &bytes_read)) != S_FALSE) {
    EXPECT_TRUE(SUCCEEDED(hr));
    EXPECT_GT(bytes_read, static_cast<ULONG>(0));

    write_pos += bytes_read;
    bytes_read = 0;
  }

  EXPECT_EQ(S_FALSE, hr);
  EXPECT_TRUE((write_pos + bytes_read) == kBigBufferLength);
  EXPECT_EQ(0, memcmp(big_buffer, big_rcv_buffer, kBigBufferLength));
}

TEST(UrlmonUploadDataStreamTest, TestStat) {
  char random_string[] = "some random data, no really this totally random";
  int random_string_length = strlen(random_string);
  scoped_refptr<net::UploadData> upload_data = new net::UploadData();
  upload_data->AppendBytes(random_string, random_string_length);

  CComObject<UrlmonUploadDataStream>* upload_stream = NULL;
  HRESULT hr =
      CComObject<UrlmonUploadDataStream>::CreateInstance(&upload_stream);
  ASSERT_TRUE(SUCCEEDED(hr));

  upload_stream->Initialize(upload_data.get());
  base::win::ScopedComPtr<IStream> upload_istream(upload_stream);

  STATSTG statstg;
  hr = upload_stream->Stat(&statstg, STATFLAG_NONAME);
  EXPECT_TRUE(SUCCEEDED(hr));
  EXPECT_EQ(static_cast<LONGLONG>(random_string_length),
            statstg.cbSize.QuadPart);
}

TEST(UrlmonUploadDataStreamTest, TestRepeatedRead) {
  char random_string[] = "some random data, no really this totally random";
  int random_string_length = strlen(random_string);
  scoped_refptr<net::UploadData> upload_data = new net::UploadData();
  upload_data->AppendBytes(random_string, random_string_length);

  CComObject<UrlmonUploadDataStream>* upload_stream = NULL;
  HRESULT hr =
      CComObject<UrlmonUploadDataStream>::CreateInstance(&upload_stream);
  ASSERT_TRUE(SUCCEEDED(hr));

  upload_stream->Initialize(upload_data.get());
  base::win::ScopedComPtr<IStream> upload_istream(upload_stream);

  char buffer[500];
  memset(buffer, 0, 500);
  ULONG bytes_read = 0;
  hr = upload_istream->Read(buffer, 500, &bytes_read);

  EXPECT_TRUE(SUCCEEDED(hr));
  EXPECT_EQ(bytes_read, random_string_length);
  EXPECT_EQ(0, strcmp(buffer, random_string));

  char buffer2[500];
  memset(buffer2, 0, 500);
  ULONG bytes_read2 = 0;

  for (int i = 0; i < 10; i++) {
    hr = upload_istream->Read(buffer2, 500, &bytes_read2);
    EXPECT_EQ(S_FALSE, hr);
    EXPECT_EQ(bytes_read2, 0);
    EXPECT_NE(0, strcmp(buffer2, random_string));
  }
}

TEST(UrlmonUploadDataStreamTest, TestZeroRead) {
  char random_string[] = "some random data, no really this totally random";
  int random_string_length = strlen(random_string);
  scoped_refptr<net::UploadData> upload_data = new net::UploadData();
  upload_data->AppendBytes(random_string, random_string_length);

  CComObject<UrlmonUploadDataStream>* upload_stream = NULL;
  HRESULT hr =
      CComObject<UrlmonUploadDataStream>::CreateInstance(&upload_stream);
  ASSERT_TRUE(SUCCEEDED(hr));

  upload_stream->Initialize(upload_data.get());
  base::win::ScopedComPtr<IStream> upload_istream(upload_stream);

  char buffer[500];
  memset(buffer, 0, 500);
  ULONG bytes_read = 42;
  hr = upload_istream->Read(&buffer[0], 0, &bytes_read);

  EXPECT_EQ(S_OK, hr);
  EXPECT_EQ(0, bytes_read);

  char buffer2[500];
  memset(&buffer2[0], 0, 500);
  EXPECT_EQ(0, memcmp(buffer, buffer2, 500));
}

