// Copyright 2015 The Cobalt Authors. 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 <string.h>

#include "starboard/file.h"
#include "starboard/memory.h"
#include "starboard/nplb/file_helpers.h"
#include "starboard/string.h"
#include "starboard/system.h"
#include "starboard/time.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

// Size of appropriate path buffer.
const size_t kPathSize = SB_FILE_MAX_PATH + 1;

void BasicTest(SbSystemPathId id,
               bool expect_result,
               bool expected_result,
               int line) {
#define LOCAL_CONTEXT "Context : id=" << id << ", line=" << line;
  char path[kPathSize];
  SbMemorySet(path, 0xCD, kPathSize);
  bool result = SbSystemGetPath(id, path, kPathSize);
  if (expect_result) {
    EXPECT_EQ(expected_result, result) << LOCAL_CONTEXT;
  }
  if (result) {
    EXPECT_NE('\xCD', path[0]) << LOCAL_CONTEXT;
    int len = static_cast<int>(SbStringGetLength(path));
    EXPECT_GT(len, 0) << LOCAL_CONTEXT;
  } else {
    EXPECT_EQ('\xCD', path[0]) << LOCAL_CONTEXT;
  }
#undef LOCAL_CONTEXT
}

TEST(SbSystemGetPathTest, ReturnsRequiredPaths) {
  BasicTest(kSbSystemPathContentDirectory, true, true, __LINE__);
  BasicTest(kSbSystemPathCacheDirectory, true, true, __LINE__);
}

TEST(SbSystemGetPathTest, FailsGracefullyZeroBufferLength) {
  char path[kPathSize] = {0};
  bool result = SbSystemGetPath(kSbSystemPathContentDirectory, path, 0);
  EXPECT_FALSE(result);
}

TEST(SbSystemGetPathTest, FailsGracefullyNullBuffer) {
  char path[kPathSize] = {0};
  bool result = SbSystemGetPath(kSbSystemPathContentDirectory, NULL, kPathSize);
  EXPECT_FALSE(result);
}

TEST(SbSystemGetPathTest, FailsGracefullyNullBufferAndZeroLength) {
  bool result = SbSystemGetPath(kSbSystemPathContentDirectory, NULL, 0);
  EXPECT_FALSE(result);
}

TEST(SbSystemGetPathTest, FailsGracefullyBogusId) {
  BasicTest(static_cast<SbSystemPathId>(999), true, false, __LINE__);
}

TEST(SbSystemGetPathTest, DoesNotBlowUpForDefinedIds) {
  BasicTest(kSbSystemPathDebugOutputDirectory, false, false, __LINE__);
  BasicTest(kSbSystemPathTempDirectory, false, false, __LINE__);
  BasicTest(kSbSystemPathTestOutputDirectory, false, false, __LINE__);
  BasicTest(kSbSystemPathCacheDirectory, false, false, __LINE__);
  BasicTest(kSbSystemPathFontDirectory, false, false, __LINE__);
  BasicTest(kSbSystemPathFontConfigurationDirectory, false, false, __LINE__);
}

TEST(SbSystemGetPathTest, CanCreateAndRemoveDirectoryInCache) {
  char path[kPathSize];
  SbMemorySet(path, 0xCD, kPathSize);
  bool result = SbSystemGetPath(kSbSystemPathCacheDirectory, path, kPathSize);
  EXPECT_TRUE(result);
  if (result) {
    EXPECT_NE('\xCD', path[0]);
    // Delete a directory and confirm that it does not exist.
    std::string sub_path =
        SB_FILE_SEP_STRING + ScopedRandomFile::MakeRandomFilename();
    EXPECT_GT(SbStringConcat(path, sub_path.c_str(), kPathSize), 0);
    EXPECT_TRUE(SbFileDelete(path));
    EXPECT_FALSE(SbFileExists(path));

    // Create the directory and confirm it exists and can be opened.
    EXPECT_TRUE(SbDirectoryCreate(path));
    EXPECT_TRUE(SbFileExists(path));
    EXPECT_TRUE(SbDirectoryCanOpen(path));
    SbDirectory directory = SbDirectoryOpen(path, NULL);
    EXPECT_TRUE(SbDirectoryIsValid(directory));

    // Lastly, close and delete the directory.
    EXPECT_TRUE(SbDirectoryClose(directory));
    EXPECT_TRUE(SbFileDelete(path));
    EXPECT_FALSE(SbFileExists(path));
  }
}

TEST(SbSystemGetPathTest, CanWriteAndReadCache) {
  char path[kPathSize];
  SbMemorySet(path, 0xCD, kPathSize);
  bool result = SbSystemGetPath(kSbSystemPathCacheDirectory, path, kPathSize);
  EXPECT_TRUE(result);
  if (result) {
    EXPECT_NE('\xCD', path[0]);
    int len = static_cast<int>(SbStringGetLength(path));
    EXPECT_GT(len, 0);
    // Delete a file and confirm that it does not exist.
    std::string sub_path =
        SB_FILE_SEP_STRING + ScopedRandomFile::MakeRandomFilename();
    EXPECT_GT(SbStringConcat(path, sub_path.c_str(), kPathSize), 0);
    EXPECT_TRUE(SbFileDelete(path));
    EXPECT_FALSE(SbFileExists(path));

    // Write to the file and check that we can read from it.
    std::string content_to_write = "test content";
    {
      starboard::ScopedFile test_file_writer(
          path, kSbFileCreateAlways | kSbFileWrite, NULL, NULL);
      EXPECT_GT(
          test_file_writer.WriteAll(content_to_write.c_str(),
                                    static_cast<int>(content_to_write.size())),
          0);
    }
    EXPECT_TRUE(SbFileExists(path));
    SbFileInfo info;
    EXPECT_TRUE(SbFileGetPathInfo(path, &info));
    const int kFileSize = static_cast<int>(info.size);
    EXPECT_GT(kFileSize, 0);
    const int kBufferLength = 16 * 1024;
    char content_read[kBufferLength] = {0};
    {
      starboard::ScopedFile test_file_reader(
          path, kSbFileOpenOnly | kSbFileRead, NULL, NULL);
      EXPECT_GT(test_file_reader.ReadAll(content_read, kFileSize), 0);
    }
    EXPECT_EQ(content_read, content_to_write);

    // Lastly, delete the file.
    EXPECT_TRUE(SbFileDelete(path));
    EXPECT_FALSE(SbFileExists(path));
  }
}

TEST(SbSystemGetPath, ExecutableFileCreationTimeIsSound) {
  // Verify that the creation time of the current executable file is not
  // greater than the current time.
  char path[kPathSize];
  SbMemorySet(path, 0xCD, kPathSize);
  bool result = SbSystemGetPath(kSbSystemPathExecutableFile, path, kPathSize);
  ASSERT_TRUE(result);

  EXPECT_NE('\xCD', path[0]);
  int len = static_cast<int>(SbStringGetLength(path));
  EXPECT_GT(len, 0);

  SbFileInfo executable_file_info;
  result = SbFileGetPathInfo(path, &executable_file_info);
  ASSERT_TRUE(result);

  SbTime now = SbTimeGetNow();
  EXPECT_GT(now, executable_file_info.creation_time);
}

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