// Copyright (c) 2012 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 <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <vector>

#include <base/string_util.h>
#include <base/stringprintf.h>
#include <base/time.h>
#include <glib.h>
#include <gtest/gtest.h>

#include "update_engine/subprocess.h"
#include "update_engine/test_utils.h"
#include "update_engine/utils.h"

using base::TimeDelta;
using std::string;
using std::vector;

namespace chromeos_update_engine {

class SubprocessTest : public ::testing::Test {
 protected:
  bool callback_done;
};

namespace {
const int kLocalHttpPort = 8088;

void Callback(int return_code, const string& output, void *p) {
  EXPECT_EQ(1, return_code);
  GMainLoop* loop = reinterpret_cast<GMainLoop*>(p);
  g_main_loop_quit(loop);
}

void CallbackEcho(int return_code, const string& output, void *p) {
  EXPECT_EQ(0, return_code);
  EXPECT_NE(string::npos, output.find("this is stdout"));
  EXPECT_NE(string::npos, output.find("this is stderr"));
  GMainLoop* loop = reinterpret_cast<GMainLoop*>(p);
  g_main_loop_quit(loop);
}

gboolean LaunchFalseInMainLoop(gpointer data) {
  vector<string> cmd;
  cmd.push_back("/bin/false");
  Subprocess::Get().Exec(cmd, Callback, data);
  return FALSE;
}

gboolean LaunchEchoInMainLoop(gpointer data) {
  vector<string> cmd;
  cmd.push_back("/bin/sh");
  cmd.push_back("-c");
  cmd.push_back("echo this is stdout; echo this is stderr > /dev/stderr");
  Subprocess::Get().Exec(cmd, CallbackEcho, data);
  return FALSE;
}
}  // namespace {}

TEST(SubprocessTest, SimpleTest) {
  GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
  g_timeout_add(0, &LaunchFalseInMainLoop, loop);
  g_main_loop_run(loop);
  g_main_loop_unref(loop);
}

TEST(SubprocessTest, EchoTest) {
  GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
  g_timeout_add(0, &LaunchEchoInMainLoop, loop);
  g_main_loop_run(loop);
  g_main_loop_unref(loop);
}

TEST(SubprocessTest, SynchronousEchoTest) {
  vector<string> cmd;
  cmd.push_back("/bin/sh");
  cmd.push_back("-c");
  cmd.push_back("echo -n stdout-here; echo -n stderr-there > /dev/stderr");
  int rc = -1;
  string stdout;
  ASSERT_TRUE(Subprocess::SynchronousExec(cmd, &rc, &stdout));
  EXPECT_EQ(0, rc);
  EXPECT_EQ("stdout-herestderr-there", stdout);
}

TEST(SubprocessTest, SynchronousEchoNoOutputTest) {
  vector<string> cmd;
  cmd.push_back("/bin/sh");
  cmd.push_back("-c");
  cmd.push_back("echo test");
  int rc = -1;
  ASSERT_TRUE(Subprocess::SynchronousExec(cmd, &rc, NULL));
  EXPECT_EQ(0, rc);
}

namespace {
void CallbackBad(int return_code, const string& output, void *p) {
  CHECK(false) << "should never be called.";
}

struct CancelTestData {
  bool spawned;
  GMainLoop *loop;
};

gboolean StartAndCancelInRunLoop(gpointer data) {
  CancelTestData* cancel_test_data = reinterpret_cast<CancelTestData*>(data);
  vector<string> cmd;
  cmd.push_back("./test_http_server");
  cmd.push_back(StringPrintf("%d", kLocalHttpPort));
  uint32_t tag = Subprocess::Get().Exec(cmd, CallbackBad, NULL);
  EXPECT_NE(0, tag);
  cancel_test_data->spawned = true;
  printf("spawned\n");
  // Wait for server to be up and running
  TimeDelta total_wait_time;
  const TimeDelta kSleepTime = TimeDelta::FromMilliseconds(100);
  const TimeDelta kMaxWaitTime = TimeDelta::FromSeconds(3);
  for (;;) {
    int status =
        System(StringPrintf("wget -O /dev/null http://127.0.0.1:%d/foo",
                            kLocalHttpPort));
    EXPECT_NE(-1, status) << "system() failed";
    EXPECT_TRUE(WIFEXITED(status))
        << "command failed to run or died abnormally";
    if (0 == WEXITSTATUS(status))
      break;

    g_usleep(kSleepTime.InMicroseconds());
    total_wait_time += kSleepTime;
    CHECK_LT(total_wait_time.InMicroseconds(), kMaxWaitTime.InMicroseconds());
  }
  Subprocess::Get().CancelExec(tag);
  return FALSE;
}
}  // namespace {}

gboolean ExitWhenDone(gpointer data) {
  CancelTestData* cancel_test_data = reinterpret_cast<CancelTestData*>(data);
  if (cancel_test_data->spawned && !Subprocess::Get().SubprocessInFlight()) {
    // tear down the sub process
    printf("tear down time\n");
    int status = System(
        StringPrintf("wget -O /dev/null http://127.0.0.1:%d/quitquitquit",
                     kLocalHttpPort));
    EXPECT_NE(-1, status) << "system() failed";
    EXPECT_TRUE(WIFEXITED(status))
        << "command failed to run or died abnormally";
    g_main_loop_quit(cancel_test_data->loop);
    return FALSE;
  }
  return TRUE;
}

TEST(SubprocessTest, CancelTest) {
  GMainLoop *loop = g_main_loop_new(g_main_context_default(), FALSE);
  CancelTestData cancel_test_data;
  cancel_test_data.spawned = false;
  cancel_test_data.loop = loop;
  g_timeout_add(100, &StartAndCancelInRunLoop, &cancel_test_data);
  g_timeout_add(10, &ExitWhenDone, &cancel_test_data);
  g_main_loop_run(loop);
  g_main_loop_unref(loop);
  printf("here\n");
}

}  // namespace chromeos_update_engine
