// 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 <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <poll.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>
#include <vector>

#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <base/time/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 {
int local_server_port = 0;

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, nullptr));
  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;
};

// TODO(garnold) this test method uses test_http_server as a representative for
// interactive processes that can be spawned/terminated at will. This causes us
// to go through hoops when spawning this process (e.g. obtaining the port
// number it uses so we can control it with wget). It would have been much
// preferred to use something else and thus simplify both test_http_server
// (doesn't have to be able to communicate through a temp file) and the test
// code below; for example, it sounds like a brain dead sleep loop with proper
// signal handlers could be used instead.
gboolean StartAndCancelInRunLoop(gpointer data) {
  CancelTestData* cancel_test_data = reinterpret_cast<CancelTestData*>(data);

  // Create a temp file for test_http_server to communicate its port number.
  char temp_file_name[] = "/tmp/subprocess_unittest-test_http_server-XXXXXX";
  int temp_fd = mkstemp(temp_file_name);
  CHECK_GE(temp_fd, 0);
  int temp_flags = fcntl(temp_fd, F_GETFL, 0) | O_NONBLOCK;
  CHECK_EQ(fcntl(temp_fd, F_SETFL, temp_flags), 0);

  vector<string> cmd;
  cmd.push_back("./test_http_server");
  cmd.push_back(temp_file_name);
  uint32_t tag = Subprocess::Get().Exec(cmd, CallbackBad, nullptr);
  EXPECT_NE(0, tag);
  cancel_test_data->spawned = true;
  printf("test http server 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);
  local_server_port = 0;
  static const char* kServerListeningMsgPrefix = "listening on port ";
  while (total_wait_time.InMicroseconds() < kMaxWaitTime.InMicroseconds()) {
    char line[80];
    int line_len = read(temp_fd, line, sizeof(line) - 1);
    if (line_len > 0) {
      line[line_len] = '\0';
      CHECK_EQ(strstr(line, kServerListeningMsgPrefix), line);
      const char* listening_port_str =
          line + strlen(kServerListeningMsgPrefix);
      char* end_ptr;
      long raw_port = strtol(listening_port_str,  // NOLINT(runtime/int)
                             &end_ptr, 10);
      CHECK(!*end_ptr || *end_ptr == '\n');
      local_server_port = static_cast<in_port_t>(raw_port);
      break;
    } else if (line_len < 0 && errno != EAGAIN) {
      LOG(INFO) << "error reading from " << temp_file_name << ": "
                << strerror(errno);
      break;
    }
    g_usleep(kSleepTime.InMicroseconds());
    total_wait_time += kSleepTime;
  }
  close(temp_fd);
  remove(temp_file_name);
  CHECK_GT(local_server_port, 0);
  LOG(INFO) << "server listening on port " << local_server_port;
  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(
        base::StringPrintf("wget -O /dev/null http://127.0.0.1:%d/quitquitquit",
                           local_server_port));
    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);
}

}  // namespace chromeos_update_engine
