// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>
#include <stdint.h>

#include <string>

#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "content/browser/download/save_file_manager.h"
#include "content/browser/download/save_package.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/public/common/url_constants.h"
#include "content/test/test_render_view_host.h"
#include "content/test/test_web_contents.h"
#include "net/test/url_request/url_request_mock_http_job.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace content {

#define FPL FILE_PATH_LITERAL
#define HTML_EXTENSION ".html"
#if defined(OS_WIN)
#define FPL_HTML_EXTENSION L".html"
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
#define FPL_HTML_EXTENSION ".html"
#endif

namespace {

// This constant copied from save_package.cc.
#if defined(OS_WIN)
const uint32_t kMaxFilePathLength = MAX_PATH - 1;
const uint32_t kMaxFileNameLength = MAX_PATH - 1;
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
const uint32_t kMaxFilePathLength = PATH_MAX - 1;
const uint32_t kMaxFileNameLength = NAME_MAX;
#endif

bool HasOrdinalNumber(const base::FilePath::StringType& filename) {
  base::FilePath::StringType::size_type r_paren_index =
      filename.rfind(FPL(')'));
  base::FilePath::StringType::size_type l_paren_index =
      filename.rfind(FPL('('));
  if (l_paren_index >= r_paren_index)
    return false;

  for (base::FilePath::StringType::size_type i = l_paren_index + 1;
       i != r_paren_index; ++i) {
    if (!base::IsAsciiDigit(filename[i]))
      return false;
  }

  return true;
}

}  // namespace

class SavePackageTest : public RenderViewHostImplTestHarness {
 public:
  bool GetGeneratedFilename(bool need_success_generate_filename,
                            const std::string& disposition,
                            const std::string& url,
                            bool need_htm_ext,
                            base::FilePath::StringType* generated_name) {
    SavePackage* save_package;
    if (need_success_generate_filename)
      save_package = save_package_success_.get();
    else
      save_package = save_package_fail_.get();
    return save_package->GenerateFileName(disposition, GURL(url), need_htm_ext,
                                          generated_name);
  }

  GURL GetUrlToBeSaved() {
    return SavePackage::GetUrlToBeSaved(save_package_success_->web_contents());
  }

 protected:
  void SetUp() override {
    RenderViewHostImplTestHarness::SetUp();

    // Do the initialization in SetUp so contents() is initialized by
    // RenderViewHostImplTestHarness::SetUp.
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    save_package_success_ = new SavePackage(
        contents(), SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
        temp_dir_.GetPath().AppendASCII("testfile" HTML_EXTENSION),
        temp_dir_.GetPath().AppendASCII("testfile_files"));

    base::FilePath::StringType long_file_name = GetLongFileName();
    save_package_fail_ = new SavePackage(
        contents(), SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
        temp_dir_.GetPath().Append(long_file_name + FPL_HTML_EXTENSION),
        temp_dir_.GetPath().Append(long_file_name + FPL("_files")));
  }

  BrowserContext* CreateBrowserContext() override {
    // This method is invoked after the browser threads have been created and
    // obviously before the BrowserContext is created. This is the correct time
    // to create a ResourceDispatcherHostImpl so that our SavePackage objects
    // can initialize correctly.
    rdh_.reset(new ResourceDispatcherHostImpl);
    // Initialize the SaveFileManager instance which we will use for the tests.
    save_file_manager_ = new SaveFileManager();
    return RenderViewHostImplTestHarness::CreateBrowserContext();
  }

  void TearDown() override {
    DeleteContents();
    base::RunLoop().RunUntilIdle();

    save_package_success_ = nullptr;
    save_package_fail_ = nullptr;
    rdh_.reset();

    RenderViewHostImplTestHarness::TearDown();
  }

  // Returns a path that is *almost* kMaxFilePathLength long
  base::FilePath::StringType GetLongFileName() const {
    size_t target_length =
        kMaxFilePathLength - 9 - temp_dir_.GetPath().value().length();
    return base::FilePath::StringType(target_length, FPL('a'));
  }

 private:
  // SavePackage for successfully generating file name.
  scoped_refptr<SavePackage> save_package_success_;
  // SavePackage for failed generating file name.
  scoped_refptr<SavePackage> save_package_fail_;

  base::ScopedTempDir temp_dir_;

  std::unique_ptr<ResourceDispatcherHostImpl> rdh_;
  scoped_refptr<SaveFileManager> save_file_manager_;
};

static const struct {
  const char* disposition;
  const char* url;
  const base::FilePath::CharType* expected_name;
  bool need_htm_ext;
} kGeneratedFiles[] = {
  // We mainly focus on testing duplicated names here, since retrieving file
  // name from disposition and url has been tested in DownloadManagerTest.

  // No useful information in disposition or URL, use default.
  {"1.html", "http://www.savepage.com/",
    FPL("saved_resource") FPL_HTML_EXTENSION, true},

  // No duplicate occurs.
  {"filename=1.css", "http://www.savepage.com", FPL("1.css"), false},

  // No duplicate occurs.
  {"filename=1.js", "http://www.savepage.com", FPL("1.js"), false},

  // Append numbers for duplicated names.
  {"filename=1.css", "http://www.savepage.com", FPL("1(1).css"), false},

  // No duplicate occurs.
  {"filename=1(1).js", "http://www.savepage.com", FPL("1(1).js"), false},

  // Append numbers for duplicated names.
  {"filename=1.css", "http://www.savepage.com", FPL("1(2).css"), false},

  // Change number for duplicated names.
  {"filename=1(1).css", "http://www.savepage.com", FPL("1(3).css"), false},

  // No duplicate occurs.
  {"filename=1(11).css", "http://www.savepage.com", FPL("1(11).css"), false},

  // Test for case-insensitive file names.
  {"filename=readme.txt", "http://www.savepage.com",
                          FPL("readme.txt"), false},

  {"filename=readme.TXT", "http://www.savepage.com",
                          FPL("readme(1).TXT"), false},

  {"filename=READme.txt", "http://www.savepage.com",
                          FPL("readme(2).txt"), false},

  {"filename=Readme(1).txt", "http://www.savepage.com",
                          FPL("readme(3).txt"), false},
};

TEST_F(SavePackageTest, TestSuccessfullyGenerateSavePackageFilename) {
  for (size_t i = 0; i < base::size(kGeneratedFiles); ++i) {
    base::FilePath::StringType file_name;
    bool ok = GetGeneratedFilename(true,
                                   kGeneratedFiles[i].disposition,
                                   kGeneratedFiles[i].url,
                                   kGeneratedFiles[i].need_htm_ext,
                                   &file_name);
    ASSERT_TRUE(ok);
    EXPECT_EQ(kGeneratedFiles[i].expected_name, file_name);
  }
}

TEST_F(SavePackageTest, TestUnSuccessfullyGenerateSavePackageFilename) {
  for (size_t i = 0; i < base::size(kGeneratedFiles); ++i) {
    base::FilePath::StringType file_name;
    bool ok = GetGeneratedFilename(false,
                                   kGeneratedFiles[i].disposition,
                                   kGeneratedFiles[i].url,
                                   kGeneratedFiles[i].need_htm_ext,
                                   &file_name);
    ASSERT_FALSE(ok);
  }
}

// Crashing on Windows, see http://crbug.com/79365
#if defined(OS_WIN)
#define MAYBE_TestLongSavePackageFilename DISABLED_TestLongSavePackageFilename
#else
#define MAYBE_TestLongSavePackageFilename TestLongSavePackageFilename
#endif
TEST_F(SavePackageTest, MAYBE_TestLongSavePackageFilename) {
  const std::string base_url("http://www.google.com/");
  const base::FilePath::StringType long_file_name =
      GetLongFileName() + FPL(".css");
  const std::string url =
      base_url + base::FilePath(long_file_name).AsUTF8Unsafe();

  base::FilePath::StringType filename;
  // Test that the filename is successfully shortened to fit.
  ASSERT_TRUE(GetGeneratedFilename(true, std::string(), url, false, &filename));
  EXPECT_TRUE(filename.length() < long_file_name.length());
  EXPECT_FALSE(HasOrdinalNumber(filename));

  // Test that the filename is successfully shortened to fit, and gets an
  // an ordinal appended.
  ASSERT_TRUE(GetGeneratedFilename(true, std::string(), url, false, &filename));
  EXPECT_TRUE(filename.length() < long_file_name.length());
  EXPECT_TRUE(HasOrdinalNumber(filename));

  // Test that the filename is successfully shortened to fit, and gets a
  // different ordinal appended.
  base::FilePath::StringType filename2;
  ASSERT_TRUE(
      GetGeneratedFilename(true, std::string(), url, false, &filename2));
  EXPECT_TRUE(filename2.length() < long_file_name.length());
  EXPECT_TRUE(HasOrdinalNumber(filename2));
  EXPECT_NE(filename, filename2);
}

// Crashing on Windows, see http://crbug.com/79365
#if defined(OS_WIN)
#define MAYBE_TestLongSafePureFilename DISABLED_TestLongSafePureFilename
#else
#define MAYBE_TestLongSafePureFilename TestLongSafePureFilename
#endif
TEST_F(SavePackageTest, MAYBE_TestLongSafePureFilename) {
  const base::FilePath save_dir(FPL("test_dir"));
  const base::FilePath::StringType ext(FPL_HTML_EXTENSION);
  base::FilePath::StringType filename = GetLongFileName();

  // Test that the filename + extension doesn't exceed kMaxFileNameLength
  uint32_t max_path = SavePackage::GetMaxPathLengthForDirectory(save_dir);
  ASSERT_TRUE(SavePackage::TruncateBaseNameToFitPathConstraints(
      save_dir, ext, max_path, &filename));
  EXPECT_TRUE(filename.length() <= kMaxFileNameLength-ext.length());
}

// GetUrlToBeSaved method should return correct url to be saved.
TEST_F(SavePackageTest, TestGetUrlToBeSaved) {
  GURL url = net::URLRequestMockHTTPJob::GetMockUrl("save_page/a.htm");
  NavigateAndCommit(url);
  EXPECT_EQ(url, GetUrlToBeSaved());
}

// GetUrlToBeSaved method sould return actual url to be saved,
// instead of the displayed url used to view source of a page.
// Ex:GetUrlToBeSaved method should return http://www.google.com
// when user types view-source:http://www.google.com
TEST_F(SavePackageTest, TestGetUrlToBeSavedViewSource) {
  GURL mock_url = net::URLRequestMockHTTPJob::GetMockUrl("save_page/a.htm");
  GURL view_source_url =
      GURL(kViewSourceScheme + std::string(":") + mock_url.spec());
  GURL actual_url = net::URLRequestMockHTTPJob::GetMockUrl("save_page/a.htm");
  NavigateAndCommit(view_source_url);
  EXPECT_EQ(actual_url, GetUrlToBeSaved());
  EXPECT_EQ(view_source_url, contents()->GetLastCommittedURL());
}

}  // namespace content
