//
// Copyright (C) 2012 The Android Open Source Project
//
// 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 "shill/external_task.h"

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/files/file_path.h>
#include <base/memory/weak_ptr.h>
#include <base/strings/string_util.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "shill/mock_adaptors.h"
#include "shill/mock_process_manager.h"
#include "shill/nice_mock_control.h"
#include "shill/test_event_dispatcher.h"

using std::map;
using std::string;
using std::vector;
using testing::_;
using testing::MatchesRegex;
using testing::Mock;
using testing::NiceMock;
using testing::Return;

namespace shill {

class ExternalTaskTest : public testing::Test,
                         public RPCTaskDelegate {
 public:
  ExternalTaskTest()
      : weak_ptr_factory_(this),
        death_callback_(
          base::Bind(&ExternalTaskTest::TaskDiedCallback,
                     weak_ptr_factory_.GetWeakPtr())),
        external_task_(
            new ExternalTask(&control_, &process_manager_,
                             weak_ptr_factory_.GetWeakPtr(),
                             death_callback_)),
        test_rpc_task_destroyed_(false) {}

  virtual ~ExternalTaskTest() {}

  void TearDown() override {
    if (!external_task_) {
      return;
    }

    if (external_task_->pid_) {
      EXPECT_CALL(process_manager_, StopProcess(external_task_->pid_));
    }
  }

  void set_test_rpc_task_destroyed(bool destroyed) {
    test_rpc_task_destroyed_ = destroyed;
  }

  // Defined out-of-line, due to dependency on TestRPCTask.
  void FakeUpRunningProcess(unsigned int tag, int pid);

  void ExpectStop(unsigned int tag, int pid) {
    EXPECT_CALL(process_manager_, StopProcess(pid));
  }

  void VerifyStop() {
    if (external_task_) {
      EXPECT_EQ(0, external_task_->pid_);
      EXPECT_FALSE(external_task_->rpc_task_);
    }
    EXPECT_TRUE(test_rpc_task_destroyed_);
    // Make sure EXPECTations were met before the fixture's dtor.
    Mock::VerifyAndClearExpectations(&process_manager_);
  }

 protected:
  // Implements RPCTaskDelegate interface.
  MOCK_METHOD2(GetLogin, void(string* user, string* password));
  MOCK_METHOD2(Notify, void(const string& reason,
                            const map<string, string>& dict));

  MOCK_METHOD2(TaskDiedCallback, void(pid_t pid, int exit_status));

  NiceMockControl control_;
  EventDispatcherForTest dispatcher_;
  MockProcessManager process_manager_;
  base::WeakPtrFactory<ExternalTaskTest> weak_ptr_factory_;
  base::Callback<void(pid_t, int)> death_callback_;
  std::unique_ptr<ExternalTask> external_task_;
  bool test_rpc_task_destroyed_;
};

namespace {

class TestRPCTask : public RPCTask {
 public:
  TestRPCTask(ControlInterface* control, ExternalTaskTest* test);
  virtual ~TestRPCTask();

 private:
  ExternalTaskTest* test_;
};

TestRPCTask::TestRPCTask(ControlInterface* control, ExternalTaskTest* test)
    : RPCTask(control, test),
      test_(test) {
  test_->set_test_rpc_task_destroyed(false);
}

TestRPCTask::~TestRPCTask() {
  test_->set_test_rpc_task_destroyed(true);
  test_ = nullptr;
}

}  // namespace

void ExternalTaskTest::FakeUpRunningProcess(unsigned int tag, int pid) {
  external_task_->pid_ = pid;
  external_task_->rpc_task_.reset(new TestRPCTask(&control_, this));
}

TEST_F(ExternalTaskTest, Destructor) {
  const unsigned int kTag = 123;
  const int kPID = 123456;
  FakeUpRunningProcess(kTag, kPID);
  ExpectStop(kTag, kPID);
  external_task_.reset();
  VerifyStop();
}

TEST_F(ExternalTaskTest, DestroyLater) {
  const unsigned int kTag = 123;
  const int kPID = 123456;
  FakeUpRunningProcess(kTag, kPID);
  ExpectStop(kTag, kPID);
  external_task_.release()->DestroyLater(&dispatcher_);
  dispatcher_.DispatchPendingEvents();
  VerifyStop();
}

TEST_F(ExternalTaskTest, Start) {
  const string kCommand = "/run/me";
  const vector<string> kCommandOptions{"arg1", "arg2"};
  const map<string, string> kCommandEnv{{"env1", "val1"}, {"env2", "val2"}};
  map<string, string> expected_env;
  expected_env.emplace(kRPCTaskServiceVariable, RPCTaskMockAdaptor::kRpcConnId);
  expected_env.emplace(kRPCTaskPathVariable, RPCTaskMockAdaptor::kRpcId);
  expected_env.insert(kCommandEnv.begin(), kCommandEnv.end());
  const int kPID = 234678;
  EXPECT_CALL(process_manager_,
              StartProcess(_, base::FilePath(kCommand), kCommandOptions,
                           expected_env, false, _))
      .WillOnce(Return(-1))
      .WillOnce(Return(kPID));
  Error error;
  EXPECT_FALSE(external_task_->Start(
      base::FilePath(kCommand), kCommandOptions, kCommandEnv, false, &error));
  EXPECT_EQ(Error::kInternalError, error.type());
  EXPECT_FALSE(external_task_->rpc_task_);

  error.Reset();
  EXPECT_TRUE(external_task_->Start(
      base::FilePath(kCommand), kCommandOptions, kCommandEnv, false, &error));
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_EQ(kPID, external_task_->pid_);
  EXPECT_NE(nullptr, external_task_->rpc_task_);
}

TEST_F(ExternalTaskTest, Stop) {
  const unsigned int kTag = 123;
  const int kPID = 123456;
  FakeUpRunningProcess(kTag, kPID);
  ExpectStop(kTag, kPID);
  external_task_->Stop();
  ASSERT_NE(nullptr, external_task_);
  VerifyStop();
}

TEST_F(ExternalTaskTest, StopNotStarted) {
  EXPECT_CALL(process_manager_, StopProcess(_)).Times(0);
  external_task_->Stop();
  EXPECT_FALSE(test_rpc_task_destroyed_);
}

TEST_F(ExternalTaskTest, GetLogin) {
  string username;
  string password;
  EXPECT_CALL(*this, GetLogin(&username, &password));
  EXPECT_CALL(*this, Notify(_, _)).Times(0);
  external_task_->GetLogin(&username, &password);
}

TEST_F(ExternalTaskTest, Notify) {
  const string kReason("you may already have won!");
  const map<string, string>& kArgs{
    {"arg1", "val1"},
    {"arg2", "val2"}};
  EXPECT_CALL(*this, GetLogin(_, _)).Times(0);
  EXPECT_CALL(*this, Notify(kReason, kArgs));
  external_task_->Notify(kReason, kArgs);
}

TEST_F(ExternalTaskTest, OnTaskDied) {
  const int kPID = 99999;
  const int kExitStatus = 1;
  external_task_->pid_ = kPID;
  EXPECT_CALL(process_manager_, StopProcess(_)).Times(0);
  EXPECT_CALL(*this, TaskDiedCallback(kPID, kExitStatus));
  external_task_->OnTaskDied(kExitStatus);
  EXPECT_EQ(0, external_task_->pid_);
}

}  // namespace shill
