// Copyright 2011 Google Inc.
//
// 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 "syzygy/wsdump/process_working_set.h"

#include <psapi.h>
#include <set>
#include <vector>

#include "base/at_exit.h"
#include "base/string_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/win/scoped_handle.h"
#include "gtest/gtest.h"
#include "sawbuck/common/com_utils.h"
#include "syzygy/core/address_space.h"

namespace wsdump {

class TestingProcessWorkingSet: public ProcessWorkingSet {
 public:
  using ProcessWorkingSet::ScopedWsPtr;
  using ProcessWorkingSet::CaptureWorkingSet;

  using ProcessWorkingSet::ModuleAddressSpace;
  using ProcessWorkingSet::CaptureModules;
};

TEST(ProcessWorkingSetTest, CaptureWorkingSet) {
  TestingProcessWorkingSet::ScopedWsPtr working_set;
  EXPECT_TRUE(TestingProcessWorkingSet::CaptureWorkingSet(::GetCurrentProcess(),
                                                          &working_set));
  EXPECT_TRUE(working_set.get() != NULL);
}

// This function gives us an address in our module.
static void dummy() {
}

TEST(ProcessWorkingSetTest, CaptureModules) {
  typedef TestingProcessWorkingSet::ModuleAddressSpace ModuleAddressSpace;
  ModuleAddressSpace modules;
  EXPECT_TRUE(TestingProcessWorkingSet::CaptureModules(::GetCurrentProcessId(),
                                                       &modules));
  EXPECT_LT(0U, modules.ranges().size());

  ModuleAddressSpace::Range range(reinterpret_cast<size_t>(&dummy), 1);
  EXPECT_TRUE(modules.FindContaining(range) != modules.end());
}

TEST(ProcessWorkingSetTest, Initialize) {
  ProcessWorkingSet ws;
  ASSERT_TRUE(ws.Initialize(::GetCurrentProcessId()));

  // Double-check the accounting.
  std::set<std::wstring> module_names;
  ProcessWorkingSet::Stats total_modules;
  ProcessWorkingSet::ModuleStatsVector::const_iterator it;
  for (it = ws.module_stats().begin(); it != ws.module_stats().end(); ++it) {
    const ProcessWorkingSet::ModuleStats& stats = *it;

    // Each module name must occur precisely once.
    EXPECT_TRUE(module_names.insert(stats.module_name).second);

    total_modules.pages += stats.pages;
    total_modules.shareable_pages += stats.shareable_pages;
    total_modules.shared_pages += stats.shared_pages;
    total_modules.read_only_pages += stats.read_only_pages;
    total_modules.writable_pages += stats.writable_pages;
    total_modules.executable_pages += stats.executable_pages;
  }

  // Our executable should be in the working set.
  std::wstring exe_name;
  ASSERT_TRUE(
      ::GetModuleFileName(NULL, WriteInto(&exe_name, MAX_PATH), MAX_PATH));
  exe_name.resize(wcslen(exe_name.c_str()));

  EXPECT_TRUE(module_names.find(exe_name) != module_names.end());

  // And finally check the tally.
  EXPECT_EQ(ws.total_stats().pages,
            total_modules.pages + ws.non_module_stats().pages);
  EXPECT_EQ(ws.total_stats().shareable_pages,
      total_modules.shareable_pages + ws.non_module_stats().shareable_pages);
  EXPECT_EQ(ws.total_stats().shared_pages,
      total_modules.shared_pages + ws.non_module_stats().shared_pages);
  EXPECT_EQ(ws.total_stats().read_only_pages,
      total_modules.read_only_pages + ws.non_module_stats().read_only_pages);
  EXPECT_EQ(ws.total_stats().writable_pages,
      total_modules.writable_pages + ws.non_module_stats().writable_pages);
  EXPECT_EQ(ws.total_stats().executable_pages,
      total_modules.executable_pages + ws.non_module_stats().executable_pages);
}

}  // namespace wsdump
