// Copyright (c) 2009 The Chromium OS 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 <string>
#include <vector>
#include <glib.h>
#include <pthread.h>
#include <gtest/gtest.h>
#include "update_engine/download_action.h"
#include "update_engine/install_action.h"
#include "update_engine/libcurl_http_fetcher.h"
#include "update_engine/mock_http_fetcher.h"
#include "update_engine/omaha_request_action.h"
#include "update_engine/omaha_request_prep_action.h"
#include "update_engine/omaha_response_handler_action.h"
#include "update_engine/postinstall_runner_action.h"
#include "update_engine/set_bootable_flag_action.h"
#include "update_engine/test_utils.h"
#include "update_engine/utils.h"

// The tests here integrate many Action objects together. This test that
// the objects work well together, whereas most other tests focus on a single
// action at a time.

namespace chromeos_update_engine {

using std::string;
using std::vector;

class IntegrationTest : public ::testing::Test { };

namespace {
const char* kTestDir = "/tmp/update_engine-integration-test";

class IntegrationTestProcessorDelegate : public ActionProcessorDelegate {
 public:
  IntegrationTestProcessorDelegate()
      : loop_(NULL), processing_done_called_(false) {}
  virtual ~IntegrationTestProcessorDelegate() {
    EXPECT_TRUE(processing_done_called_);
  }
  virtual void ProcessingDone(const ActionProcessor* processor, bool success) {
    processing_done_called_ = true;
    g_main_loop_quit(loop_);
  }

  virtual void ActionCompleted(ActionProcessor* processor,
                               AbstractAction* action,
                               bool success) {
    // make sure actions always succeed
    EXPECT_TRUE(success);

    // Swap in the device path for PostinstallRunnerAction with a loop device
    if (action->Type() == InstallAction::StaticType()) {
      InstallAction* install_action = static_cast<InstallAction*>(action);
      old_dev_ = install_action->GetOutputObject();
      string dev = GetUnusedLoopDevice();
      string cmd = string("losetup ") + dev + " " + kTestDir + "/dev2";
      EXPECT_EQ(0, system(cmd.c_str()));
      install_action->SetOutputObject(dev);
    } else if (action->Type() == PostinstallRunnerAction::StaticType()) {
      PostinstallRunnerAction* postinstall_runner_action =
          static_cast<PostinstallRunnerAction*>(action);
      string dev = postinstall_runner_action->GetOutputObject();
      EXPECT_EQ(0, system((string("losetup -d ") + dev).c_str()));
      postinstall_runner_action->SetOutputObject(old_dev_);
      old_dev_ = "";
    }
  }

  void set_loop(GMainLoop* loop) {
    loop_ = loop;
  }

 private:
  GMainLoop *loop_;
  bool processing_done_called_;

  // We have to change the dev for the PostinstallRunnerAction action.
  // Before that runs, we store the device here, and after it runs, we
  // restore it.
  // This is because we use a file, rather than a device, to install into,
  // but the PostinstallRunnerAction requires a real device. We set up a
  // loop device pointing to the file when necessary.
  string old_dev_;
};

gboolean TestStarter(gpointer data) {
  ActionProcessor *processor = reinterpret_cast<ActionProcessor*>(data);
  processor->StartProcessing();
  return FALSE;
}

}  // namespace {}

TEST(IntegrationTest, DISABLED_RunAsRootFullInstallTest) {
  ASSERT_EQ(0, getuid());
  GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);

  ActionProcessor processor;
  IntegrationTestProcessorDelegate delegate;
  delegate.set_loop(loop);
  processor.set_delegate(&delegate);

  // Actions:
  OmahaRequestPrepAction request_prep_action(false);
  OmahaRequestAction update_check_action(NULL, new LibcurlHttpFetcher);
  OmahaResponseHandlerAction response_handler_action;
  DownloadAction download_action(new LibcurlHttpFetcher);
  InstallAction install_action;
  PostinstallRunnerAction postinstall_runner_action;
  SetBootableFlagAction set_bootable_flag_action;

  // Enqueue the actions
  processor.EnqueueAction(&request_prep_action);
  processor.EnqueueAction(&update_check_action);
  processor.EnqueueAction(&response_handler_action);
  processor.EnqueueAction(&download_action);
  processor.EnqueueAction(&install_action);
  processor.EnqueueAction(&postinstall_runner_action);
  processor.EnqueueAction(&set_bootable_flag_action);

  // Bond them together
  BondActions(&request_prep_action, &update_check_action);
  BondActions(&update_check_action, &response_handler_action);
  BondActions(&response_handler_action, &download_action);
  BondActions(&download_action, &install_action);
  BondActions(&install_action, &postinstall_runner_action);
  BondActions(&postinstall_runner_action, &set_bootable_flag_action);

  // Set up filesystem to trick some of the actions
  ASSERT_EQ(0, System(string("rm -rf ") + kTestDir));
  ASSERT_EQ(0, system("rm -f /tmp/update_engine_test_postinst_out.txt"));
  ASSERT_EQ(0, System(string("mkdir -p ") + kTestDir + "/etc"));
  ASSERT_EQ(0, system((string("mkdir -p ") + kTestDir +
                       utils::kStatefulPartition +
                       "/etc").c_str()));
  ASSERT_TRUE(WriteFileString(string(kTestDir) + "/etc/lsb-release",
                              "GOOGLE_RELEASE=0.2.0.0\n"
                              "GOOGLE_TRACK=unittest-track"));
  ASSERT_EQ(0, System(string("touch ") + kTestDir + "/dev1"));
  ASSERT_EQ(0, System(string("touch ") + kTestDir + "/dev2"));
  ASSERT_TRUE(WriteFileVector(string(kTestDir) + "/dev", GenerateSampleMbr()));

  request_prep_action.set_root(kTestDir);
  response_handler_action.set_boot_device(string(kTestDir) + "/dev1");

  // Run the actions
  g_timeout_add(0, &TestStarter, &processor);
  g_main_loop_run(loop);
  g_main_loop_unref(loop);

  // Verify the results
  struct stat stbuf;
  ASSERT_EQ(0, lstat((string(kTestDir) + "/dev1").c_str(), &stbuf));
  EXPECT_EQ(0, stbuf.st_size);
  EXPECT_TRUE(S_ISREG(stbuf.st_mode));
  ASSERT_EQ(0, lstat((string(kTestDir) + "/dev2").c_str(), &stbuf));
  EXPECT_EQ(996147200, stbuf.st_size);
  EXPECT_TRUE(S_ISREG(stbuf.st_mode));
  ASSERT_EQ(0, lstat((string(kTestDir) + "/dev").c_str(), &stbuf));
  ASSERT_EQ(512, stbuf.st_size);
  EXPECT_TRUE(S_ISREG(stbuf.st_mode));
  vector<char> new_mbr;
  EXPECT_TRUE(utils::ReadFile((string(kTestDir) + "/dev").c_str(), &new_mbr));

  // Check bootable flag in MBR
  for (int i = 0; i < 4; i++) {
    char expected_flag = '\0';
    if (i == 1)
      expected_flag = 0x80;
    EXPECT_EQ(expected_flag, new_mbr[446 + 16 * i]);
  }
  // Check MBR signature
  EXPECT_EQ(static_cast<char>(0x55), new_mbr[510]);
  EXPECT_EQ(static_cast<char>(0xaa), new_mbr[511]);

  ASSERT_EQ(0, lstat("/tmp/update_engine_test_postinst_out.txt", &stbuf));
  EXPECT_TRUE(S_ISREG(stbuf.st_mode));
  string file_data;
  EXPECT_TRUE(utils::ReadFileToString(
      "/tmp/update_engine_test_postinst_out.txt",
      &file_data));
  EXPECT_EQ("POSTINST_DONE\n", file_data);

  // cleanup
  ASSERT_EQ(0, System(string("rm -rf ") + kTestDir));
  ASSERT_EQ(0, system("rm -f /tmp/update_engine_test_postinst_out.txt"));
}

}  // namespace chromeos_update_engine
