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

// Writing is partially tested by some of the file helpers that create files for
// the tests to operate on.

#include <string>

#include "starboard/file.h"
#include "starboard/nplb/file_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

// Sets up an empty test fixture, required for typed tests.
template <class SbFileWriteType>
class SbFileWriteTest : public testing::Test {};

class SbFileWriter {
 public:
  static int Write(SbFile file, char* data, int size) {
    return SbFileWrite(file, data, size);
  }
};

class SbFileWriterAll {
 public:
  static int Write(SbFile file, char* data, int size) {
    return SbFileWriteAll(file, data, size);
  }
};

typedef testing::Types<SbFileWriter, SbFileWriterAll> SbFileWriteTestTypes;

TYPED_TEST_CASE(SbFileWriteTest, SbFileWriteTestTypes);

const int kBufferLength = 16 * 1024;

TYPED_TEST(SbFileWriteTest, InvalidFileErrors) {
  char buffer[kBufferLength] = {0};
  int result = TypeParam::Write(kSbFileInvalid, buffer, kBufferLength);
  EXPECT_EQ(-1, result);
}

TYPED_TEST(SbFileWriteTest, BasicWriting) {
  // Choose a file size that is not an even multiple of the buffer size, but
  // is over several times the size of the buffer.
  const int kFileSize = kBufferLength * 16 / 3;
  ScopedRandomFile random_file(0, ScopedRandomFile::kDontCreate);
  const std::string& filename = random_file.filename();

  SbFile file = SbFileOpen(filename.c_str(),
                           kSbFileCreateAlways | kSbFileWrite | kSbFileRead,
                           NULL, NULL);
  ASSERT_TRUE(SbFileIsValid(file));

  // Create a bigger buffer than necessary, so we can test the memory around
  // the portion given to SbFileRead.
  char buffer[kBufferLength] = {0};

  // Initialize to some arbitrary pattern so we can verify it later.
  for (int i = 0; i < kBufferLength; ++i) {
    buffer[i] = static_cast<char>(i & 0xFF);
  }

  // Read and check the whole file.
  int total = 0;
  while (true) {
    if (total == kFileSize) {
      break;
    }

    int remaining = kFileSize - total;
    int to_write = remaining < kBufferLength ? remaining : kBufferLength;
    int bytes_written = TypeParam::Write(file, buffer, to_write);

    // Check that we didn't write more than the buffer size.
    EXPECT_GE(to_write, bytes_written);

    // Check that we didn't get an error.
    ASSERT_LT(0, bytes_written);

    total += bytes_written;
    EXPECT_EQ(total, SbFileSeek(file, kSbFileFromCurrent, 0));
  }

  // Tests reading and writing from same opened file.
  bool result = SbFileFlush(file);
  ASSERT_TRUE(result);
  int position = static_cast<int>(SbFileSeek(file, kSbFileFromBegin, 0));
  ASSERT_EQ(0, position);

  // Read and check the whole file.
  total = 0;
  int previous_total = 0;
  while (true) {
    int bytes_read = SbFileReadAll(file, buffer, kBufferLength);
    if (bytes_read == 0) {
      break;
    }

    // Check that we didn't read more than the buffer size.
    EXPECT_GE(kBufferLength, bytes_read);

    // Check that we didn't get an error.
    ASSERT_LT(0, bytes_read);

    // Do some accounting to check later.
    previous_total = total;
    total += bytes_read;

    ScopedRandomFile::ExpectPattern(previous_total, buffer, bytes_read,
                                    __LINE__);
  }

  // Check that we read the whole file.
  EXPECT_EQ(kFileSize, total);

  result = SbFileClose(file);
  EXPECT_TRUE(result);
}

TYPED_TEST(SbFileWriteTest, WriteZeroBytes) {
  ScopedRandomFile random_file(0, ScopedRandomFile::kDontCreate);
  const std::string& filename = random_file.filename();

  SbFile file = SbFileOpen(filename.c_str(), kSbFileCreateOnly | kSbFileWrite,
                           NULL, NULL);
  ASSERT_TRUE(SbFileIsValid(file));

  char buffer[kBufferLength] = {0};

  // Write zero bytes.
  for (int i = 0; i < 10; ++i) {
    int bytes_written = TypeParam::Write(file, buffer, 0);
    EXPECT_EQ(0, bytes_written);
  }

  bool result = SbFileClose(file);
  EXPECT_TRUE(result);

  file =
      SbFileOpen(filename.c_str(), kSbFileOpenOnly | kSbFileRead, NULL, NULL);
  ASSERT_TRUE(SbFileIsValid(file));
  SbFileInfo info;
  result = SbFileGetInfo(file, &info);
  EXPECT_TRUE(result);
  EXPECT_EQ(0, info.size);
  result = SbFileClose(file);
  EXPECT_TRUE(result);
}

}  // namespace
}  // namespace nplb
}  // namespace starboard
