// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "bin/file.h"
#include "bin/dartutils.h"
#include "bin/directory.h"
#include "bin/test_utils.h"
#include "platform/assert.h"
#include "platform/globals.h"
#include "vm/unit_test.h"

namespace dart {

TEST_CASE(Read) {
  const char* kFilename = bin::test::GetFileName("runtime/bin/file_test.cc");
  bin::File* file = bin::File::Open(NULL, kFilename, bin::File::kRead);
  EXPECT(file != NULL);
  char buffer[16];
  buffer[0] = '\0';
  EXPECT(file->ReadFully(buffer, 13));  // ReadFully returns true.
  buffer[13] = '\0';
  EXPECT_STREQ("// Copyright ", buffer);
  EXPECT(!file->WriteByte(1));  // Cannot write to a read-only file.
  file->Release();
}

TEST_CASE(OpenUri_RelativeFilename) {
  const char* kFilename = bin::test::GetFileName("runtime/bin/file_test.cc");
  char* encoded = reinterpret_cast<char*>(bin::DartUtils::ScopedCString(
      strlen(kFilename) * 3 + 1));
  char* t = encoded;
  // percent-encode all characters 'c'
  for (const char* p = kFilename; *p != '\0'; p++) {
    if (*p == 'c') {
      *t++ = '%';
      *t++ = '6';
      *t++ = '3';
    } else {
      *t++ = *p;
    }
  }
  *t = 0;
  bin::File* file = bin::File::OpenUri(NULL, encoded, bin::File::kRead);
  EXPECT(file != NULL);
  char buffer[16];
  buffer[0] = '\0';
  EXPECT(file->ReadFully(buffer, 13));  // ReadFully returns true.
  buffer[13] = '\0';
  EXPECT_STREQ("// Copyright ", buffer);
  EXPECT(!file->WriteByte(1));  // Cannot write to a read-only file.
  file->Release();
}

TEST_CASE(OpenUri_AbsoluteFilename) {
  const char* kRelativeFilename =
      bin::test::GetFileName("runtime/bin/file_test.cc");
  const char* kFilename = bin::File::GetCanonicalPath(NULL, kRelativeFilename);
  EXPECT_NOTNULL(kFilename);
  char* encoded = reinterpret_cast<char*>(bin::DartUtils::ScopedCString(
      strlen(kFilename) * 3 + 1));
  char* t = encoded;
  // percent-encode all characters 'c'
  for (const char* p = kFilename; *p != '\0'; p++) {
    if (*p == 'c') {
      *t++ = '%';
      *t++ = '6';
      *t++ = '3';
    } else {
      *t++ = *p;
    }
  }
  *t = 0;
  bin::File* file = bin::File::OpenUri(NULL, encoded, bin::File::kRead);
  EXPECT(file != NULL);
  char buffer[16];
  buffer[0] = '\0';
  EXPECT(file->ReadFully(buffer, 13));  // ReadFully returns true.
  buffer[13] = '\0';
  EXPECT_STREQ("// Copyright ", buffer);
  EXPECT(!file->WriteByte(1));  // Cannot write to a read-only file.
  file->Release();
}

static const char* Concat(const char* a, const char* b) {
  const intptr_t len = strlen(a) + strlen(b);
  char* c = bin::DartUtils::ScopedCString(len + 1);
  EXPECT_NOTNULL(c);
  snprintf(c, len + 1, "%s%s", a, b);
  return c;
}

TEST_CASE(OpenUri_ValidUri) {
  const char* kRelativeFilename =
      bin::test::GetFileName("runtime/bin/file_test.cc");
  const char* kAbsoluteFilename = bin::File::GetCanonicalPath(NULL,
      kRelativeFilename);
  EXPECT_NOTNULL(kAbsoluteFilename);
  const char* kFilename = Concat("file:///", kAbsoluteFilename);

  char* encoded = reinterpret_cast<char*>(bin::DartUtils::ScopedCString(
      strlen(kFilename) * 3 + 1));
  char* t = encoded;
  // percent-encode all characters 'c'
  for (const char* p = kFilename; *p != '\0'; p++) {
    if (*p == 'c') {
      *t++ = '%';
      *t++ = '6';
      *t++ = '3';
    } else {
      *t++ = *p;
    }
  }
  *t = 0;
  bin::File* file = bin::File::OpenUri(NULL, encoded, bin::File::kRead);
  EXPECT(file != NULL);
  char buffer[16];
  buffer[0] = '\0';
  EXPECT(file->ReadFully(buffer, 13));  // ReadFully returns true.
  buffer[13] = '\0';
  EXPECT_STREQ("// Copyright ", buffer);
  EXPECT(!file->WriteByte(1));  // Cannot write to a read-only file.
  file->Release();
}

TEST_CASE(OpenUri_UriWithSpaces) {
  const char* kRelativeFilename =
      bin::test::GetFileName("runtime/bin/file_test.cc");
  const char* strSystemTemp = bin::Directory::SystemTemp(NULL);
  EXPECT_NOTNULL(strSystemTemp);
  const char* kTempDir = Concat(strSystemTemp, "/foo bar");
  const char* strTempDir = bin::Directory::CreateTemp(NULL, kTempDir);
  EXPECT_NOTNULL(strTempDir);
  const char* kTargetFilename = Concat(strTempDir, "/file test.cc");
  bool result = bin::File::Copy(NULL, kRelativeFilename, kTargetFilename);
  EXPECT(result);

  const char* kAbsoluteFilename = bin::File::GetCanonicalPath(NULL,
      kTargetFilename);
  EXPECT_NOTNULL(kAbsoluteFilename);
  const char* kFilename = Concat("file:///", kAbsoluteFilename);

  char* encoded = reinterpret_cast<char*>(bin::DartUtils::ScopedCString(
      strlen(kFilename) * 3 + 1));
  char* t = encoded;
  // percent-encode all spaces
  for (const char* p = kFilename; *p != '\0'; p++) {
    if (*p == ' ') {
      *t++ = '%';
      *t++ = '2';
      *t++ = '0';
    } else {
      *t++ = *p;
    }
  }
  *t = 0;
  printf("encoded: %s\n", encoded);
  bin::File* file = bin::File::OpenUri(NULL, encoded, bin::File::kRead);
  EXPECT(file != NULL);
  char buffer[16];
  buffer[0] = '\0';
  EXPECT(file->ReadFully(buffer, 13));  // ReadFully returns true.
  buffer[13] = '\0';
  EXPECT_STREQ("// Copyright ", buffer);
  EXPECT(!file->WriteByte(1));  // Cannot write to a read-only file.
  file->Release();
  bin::Directory::Delete(NULL, strTempDir, /* recursive= */ true);
}

TEST_CASE(OpenUri_InvalidUriPercentEncoding) {
  const char* kFilename = bin::test::GetFileName("runtime/bin/file_test.cc");
  char* encoded = reinterpret_cast<char*>(bin::DartUtils::ScopedCString(
      strlen(kFilename) * 3 + 1));
  char* t = encoded;
  // percent-encode all characters 'c'
  for (const char* p = kFilename; *p != '\0'; p++) {
    if (*p == 'c') {
      *t++ = '%';
      *t++ = 'f';
      *t++ = 'o';
    } else {
      *t++ = *p;
    }
  }
  *t = 0;
  bin::File* file = bin::File::OpenUri(NULL, encoded, bin::File::kRead);
  EXPECT(file == NULL);
}

TEST_CASE(OpenUri_TruncatedUriPercentEncoding) {
  const char* kFilename = bin::test::GetFileName("runtime/bin/file_test.cc");
  char* encoded = reinterpret_cast<char*>(bin::DartUtils::ScopedCString(
      strlen(kFilename) * 3 + 1));
  char* t = encoded;
  // percent-encode all characters 'c'
  for (const char* p = kFilename; *p != '\0'; p++) {
    if (*p == 'c') {
      *t++ = '%';
      *t++ = 'f';
      *t++ = 'o';
    } else {
      *t++ = *p;
    }
  }
  *(t - 1) = 0;  // truncate last uri encoding
  bin::File* file = bin::File::OpenUri(NULL, encoded, bin::File::kRead);
  EXPECT(file == NULL);
}

TEST_CASE(FileLength) {
  const char* kFilename =
      bin::test::GetFileName("runtime/tests/vm/data/fixed_length_file");
  bin::File* file = bin::File::Open(NULL, kFilename, bin::File::kRead);
  EXPECT(file != NULL);
  EXPECT_EQ(42, file->Length());
  file->Release();
}

TEST_CASE(FilePosition) {
  char buf[42];
  const char* kFilename =
      bin::test::GetFileName("runtime/tests/vm/data/fixed_length_file");
  bin::File* file = bin::File::Open(NULL, kFilename, bin::File::kRead);
  EXPECT(file != NULL);
  EXPECT(file->ReadFully(buf, 12));
  EXPECT_EQ(12, file->Position());
  EXPECT(file->ReadFully(buf, 6));
  EXPECT_EQ(18, file->Position());
  file->Release();
}

}  // namespace dart
