// 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 <algorithm>

#include "starboard/common/string.h"
#include "starboard/configuration_constants.h"
#include "starboard/file.h"
#include "starboard/memory.h"
#include "starboard/nplb/file_helpers.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 = kSbFileMaxPath + 1;

void BasicTest(SbSystemPathId id,
               bool expect_result,
               bool expected_result,
               int line) {
#define LOCAL_CONTEXT "Context : id=" << id << ", line=" << line;
  std::vector<char> path(kPathSize);
  SbMemorySet(path.data(), 0xCD, kPathSize);
  bool result = SbSystemGetPath(id, path.data(), 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.data()));
    EXPECT_GT(len, 0) << LOCAL_CONTEXT;
  } else {
    EXPECT_EQ('\xCD', path[0]) << LOCAL_CONTEXT;
  }
#undef LOCAL_CONTEXT
}

void UnmodifiedOnFailureTest(SbSystemPathId id, int line) {
  std::vector<char> path(kPathSize);
  SbMemorySet(path.data(), 0xCD, kPathSize);
  for (size_t i = 0; i <= kPathSize; ++i) {
    if (SbSystemGetPath(id, path.data(), i)) {
      return;
    }
    for (auto ch : path) {
      ASSERT_EQ('\xCD', ch) << "Context : id=" << id << ", line=" << line;
    }
  }
}

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

TEST(SbSystemGetPathTest, FailsGracefullyZeroBufferLength) {
  std::vector<char> path(kPathSize, 0);
  bool result = SbSystemGetPath(kSbSystemPathContentDirectory, path.data(), 0);
  EXPECT_FALSE(result);
}

TEST(SbSystemGetPathTest, FailsGracefullyNullBuffer) {
  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, DoesNotTouchOutputBufferOnFailureForDefinedIds) {
  UnmodifiedOnFailureTest(kSbSystemPathDebugOutputDirectory, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPathTempDirectory, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPathTestOutputDirectory, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPathCacheDirectory, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPathFontDirectory, __LINE__);
  UnmodifiedOnFailureTest(kSbSystemPathFontConfigurationDirectory, __LINE__);
}

TEST(SbSystemGetPathTest, CanCreateAndRemoveDirectoryInCache) {
  std::vector<char> path(kPathSize);
  SbMemorySet(path.data(), 0xCD, kPathSize);
  bool result =
      SbSystemGetPath(kSbSystemPathCacheDirectory, path.data(), 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 =
        kSbFileSepString + ScopedRandomFile::MakeRandomFilename();
    EXPECT_GT(SbStringConcat(path.data(), sub_path.c_str(), kPathSize), 0);
    EXPECT_TRUE(SbFileDelete(path.data()));
    EXPECT_FALSE(SbFileExists(path.data()));

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

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

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

    // 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.data(), 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.data()));
    SbFileInfo info;
    EXPECT_TRUE(SbFileGetPathInfo(path.data(), &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.data(), 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.data()));
    EXPECT_FALSE(SbFileExists(path.data()));
  }
}

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

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

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

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

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