/*
 *  Copyright 2016 The WebRTC 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 in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <limits>
#include <memory>
#include <string>

#include "webrtc/base/gunit.h"
#include "webrtc/base/file.h"
#include "webrtc/test/testsupport/fileutils.h"

#if defined(WEBRTC_WIN)

#include "webrtc/base/win32.h"

#else  // if defined(WEBRTC_WIN)

#include <errno.h>

#endif

namespace rtc {

void RemoveFile(const std::string& path) {
#if defined(WEBRTC_WIN)
  ::DeleteFile(ToUtf16(path).c_str());
#else
  ::unlink(path.c_str());
#endif
}

int LastError() {
#if defined(WEBRTC_WIN)
  return ::GetLastError();
#else
  return errno;
#endif
}

bool VerifyBuffer(uint8_t* buffer, size_t length, uint8_t start_value) {
  for (size_t i = 0; i < length; ++i) {
    uint8_t val = start_value++;
    EXPECT_EQ(val, buffer[i]);
    if (buffer[i] != val)
      return false;
  }
  // Prevent the same buffer from being verified multiple times simply
  // because some operation that should have written to it failed
  memset(buffer, 0, length);
  return true;
}

class FileTest : public ::testing::Test {
 protected:
  std::string path_;
  void SetUp() {
    path_ = webrtc::test::TempFilename(webrtc::test::OutputPath(), "test_file");
    ASSERT_FALSE(path_.empty());
  }
  rtc::File OpenTempFile() { return rtc::File::Open(path_); }
  void TearDown() { RemoveFile(path_); }
};

TEST_F(FileTest, DoubleClose) {
  File file = OpenTempFile();
  ASSERT_TRUE(file.IsOpen()) << "Error: " << LastError();

  EXPECT_TRUE(file.Close());
  EXPECT_FALSE(file.Close());
}

TEST_F(FileTest, SimpleReadWrite) {
  File file = OpenTempFile();
  ASSERT_TRUE(file.IsOpen()) << "Error: " << LastError();

  uint8_t data[100] = {0};
  uint8_t out[100] = {0};
  for (int i = 0; i < 100; ++i) {
    data[i] = i;
  }

  EXPECT_EQ(10u, file.Write(data, 10));

  EXPECT_TRUE(file.Seek(0));
  EXPECT_EQ(10u, file.Read(out, 10));
  EXPECT_TRUE(VerifyBuffer(out, 10, 0));

  EXPECT_TRUE(file.Seek(0));
  EXPECT_EQ(100u, file.Write(data, 100));

  EXPECT_TRUE(file.Seek(0));
  EXPECT_EQ(100u, file.Read(out, 100));
  EXPECT_TRUE(VerifyBuffer(out, 100, 0));

  EXPECT_TRUE(file.Seek(1));
  EXPECT_EQ(50u, file.Write(data, 50));
  EXPECT_EQ(50u, file.Write(data + 50, 50));

  EXPECT_TRUE(file.Seek(1));
  EXPECT_EQ(100u, file.Read(out, 100));
  EXPECT_TRUE(VerifyBuffer(out, 100, 0));
}

TEST_F(FileTest, ReadWriteClose) {
  File file = OpenTempFile();
  ASSERT_TRUE(file.IsOpen()) << "Error: " << LastError();

  uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  uint8_t out[10] = {0};
  EXPECT_EQ(10u, file.Write(data, 10));
  EXPECT_TRUE(file.Close());

  File file2 = OpenTempFile();
  ASSERT_TRUE(file2.IsOpen()) << "Error: " << LastError();
  EXPECT_EQ(10u, file2.Read(out, 10));
  EXPECT_TRUE(VerifyBuffer(out, 10, 0));
}

TEST_F(FileTest, RandomAccessRead) {
  File file = OpenTempFile();
  ASSERT_TRUE(file.IsOpen()) << "Error: " << LastError();

  uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  uint8_t out[10] = {0};
  EXPECT_EQ(10u, file.Write(data, 10));

  EXPECT_EQ(4u, file.ReadAt(out, 4, 0));
  EXPECT_TRUE(VerifyBuffer(out, 4, 0));

  EXPECT_EQ(4u, file.ReadAt(out, 4, 4));
  EXPECT_TRUE(VerifyBuffer(out, 4, 4));

  EXPECT_EQ(5u, file.ReadAt(out, 5, 5));
  EXPECT_TRUE(VerifyBuffer(out, 5, 5));
}

TEST_F(FileTest, RandomAccessReadWrite) {
  File file = OpenTempFile();
  ASSERT_TRUE(file.IsOpen()) << "Error: " << LastError();

  uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  uint8_t out[10] = {0};
  EXPECT_EQ(10u, file.Write(data, 10));
  EXPECT_TRUE(file.Seek(4));

  EXPECT_EQ(4u, file.WriteAt(data, 4, 4));
  EXPECT_EQ(4u, file.ReadAt(out, 4, 4));
  EXPECT_TRUE(VerifyBuffer(out, 4, 0));

  EXPECT_EQ(2u, file.WriteAt(data, 2, 8));
  EXPECT_EQ(2u, file.ReadAt(out, 2, 8));
  EXPECT_TRUE(VerifyBuffer(out, 2, 0));
}

}  // namespace rtc
