// Copyright 2018 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 <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <gtest/gtest.h>

#include "usb_bouncer/entry_manager.h"
#include "usb_bouncer/entry_manager_test_util.h"
#include "usb_bouncer/util.h"

namespace usb_bouncer {

namespace {
enum class SessionState {
  kNoUser,
  kLockscreenShown,
  kUserPresent,
};

bool IsUserPresent(SessionState session_state) {
  switch (session_state) {
    case SessionState::kNoUser:
      return false;
    case SessionState::kLockscreenShown:
    case SessionState::kUserPresent:
      return true;
  }
}
}  // namespace

class EntryManagerTest : public testing::Test {
 public:
  void GarbageCollectTest(SessionState session_state) {
    bool user_present = IsUserPresent(session_state);
    util_.RefreshDB(user_present /*include_user_db*/, true /*new_db*/);

    EXPECT_TRUE(util_.Get()->HandleUdev(EntryManager::UdevAction::kAdd,
                                        kDefaultDevpath));
    EXPECT_TRUE(util_.Get()->HandleUdev(EntryManager::UdevAction::kRemove,
                                        kDefaultDevpath));

    bool lockscreen_is_shown = session_state == SessionState::kLockscreenShown;
    util_.SetUserDBReadOnly(lockscreen_is_shown);

    EXPECT_EQ(util_.GarbageCollectInternal(true /*global_only*/), 0);
    EXPECT_TRUE(util_.GlobalTrashContainsEntry(kDefaultDevpath, kDefaultRule));
    if (user_present) {
      EXPECT_TRUE(util_.UserDBContainsEntry(kDefaultRule));
    }

    EXPECT_TRUE(util_.Get()->GarbageCollect());
    EXPECT_TRUE(util_.GlobalTrashContainsEntry(kDefaultDevpath, kDefaultRule));
    if (user_present) {
      EXPECT_TRUE(util_.UserDBContainsEntry(kDefaultRule));
    }

    util_.ExpireEntry(user_present, kDefaultDevpath, kDefaultRule);

    EXPECT_EQ(util_.GarbageCollectInternal(true /*global_only*/), 1);
    EXPECT_FALSE(util_.GlobalTrashContainsEntry(kDefaultDevpath, kDefaultRule));
    if (user_present) {
      EXPECT_TRUE(util_.UserDBContainsEntry(kDefaultRule));
    }

    util_.SetUserDBReadOnly(false);

    EXPECT_TRUE(util_.Get()->HandleUdev(EntryManager::UdevAction::kAdd,
                                        kDefaultDevpath));
    EXPECT_TRUE(util_.Get()->HandleUdev(EntryManager::UdevAction::kRemove,
                                        kDefaultDevpath));
    util_.ExpireEntry(user_present, kDefaultDevpath, kDefaultRule);

    util_.SetUserDBReadOnly(lockscreen_is_shown);

    EXPECT_TRUE(util_.Get()->GarbageCollect());
    EXPECT_FALSE(util_.GlobalTrashContainsEntry(kDefaultDevpath, kDefaultRule));
    if (user_present) {
      EXPECT_FALSE(util_.UserDBContainsEntry(kDefaultRule));
    }
  }

  void GenerateRulesTest(SessionState session_state) {
    bool user_present = IsUserPresent(session_state);
    util_.RefreshDB(user_present /*include_user_db*/, true /*new_db*/);

    EXPECT_FALSE(util_.Get()->GenerateRules().empty());

    EXPECT_TRUE(util_.Get()->HandleUdev(EntryManager::UdevAction::kAdd,
                                        kDefaultDevpath));

    bool lockscreen_is_shown = session_state == SessionState::kLockscreenShown;
    util_.SetUserDBReadOnly(lockscreen_is_shown);

    std::string rules = util_.Get()->GenerateRules();
    EXPECT_FALSE(rules.empty());
    EXPECT_NE(rules.find(kDefaultRule, 0), std::string::npos);
  }

  void HandleUdevTest(SessionState session_state) {
    bool user_present = IsUserPresent(session_state);
    util_.RefreshDB(user_present /*include_user_db*/, true /*new_db*/);

    bool lockscreen_is_shown = session_state == SessionState::kLockscreenShown;
    util_.SetUserDBReadOnly(lockscreen_is_shown);

    EXPECT_FALSE(util_.GlobalDBContainsEntry(kDefaultDevpath, kDefaultRule));
    EXPECT_FALSE(util_.GlobalTrashContainsEntry(kDefaultDevpath, kDefaultRule));
    if (user_present) {
      EXPECT_FALSE(util_.UserDBContainsEntry(kDefaultRule));
    }
    EXPECT_TRUE(util_.Get()->HandleUdev(EntryManager::UdevAction::kAdd,
                                        kDefaultDevpath));
    EXPECT_TRUE(util_.GlobalDBContainsEntry(kDefaultDevpath, kDefaultRule));
    EXPECT_FALSE(util_.GlobalTrashContainsEntry(kDefaultDevpath, kDefaultRule));
    if (user_present) {
      EXPECT_NE(util_.UserDBContainsEntry(kDefaultRule), lockscreen_is_shown);
    }

    EXPECT_FALSE(util_.Get()->HandleUdev(EntryManager::UdevAction::kAdd, ""));
    EXPECT_FALSE(util_.Get()->HandleUdev(EntryManager::UdevAction::kAdd,
                                         kUsbguardPolicyDir));

    EXPECT_TRUE(util_.Get()->HandleUdev(EntryManager::UdevAction::kRemove,
                                        kDefaultDevpath));
    EXPECT_FALSE(util_.GlobalDBContainsEntry(kDefaultDevpath, kDefaultRule));
    EXPECT_TRUE(util_.GlobalTrashContainsEntry(kDefaultDevpath, kDefaultRule));
    if (user_present) {
      EXPECT_NE(util_.UserDBContainsEntry(kDefaultRule), lockscreen_is_shown);
    }

    EXPECT_FALSE(
        util_.Get()->HandleUdev(EntryManager::UdevAction::kRemove, ""));
  }

 protected:
  EntryManagerTestUtil util_;
};

TEST_F(EntryManagerTest, GarbageCollect_NoUser) {
  GarbageCollectTest(SessionState::kNoUser /*session_state*/);
}

TEST_F(EntryManagerTest, GarbageCollect_LockscreenShown) {
  GarbageCollectTest(SessionState::kLockscreenShown /*session_state*/);
}

TEST_F(EntryManagerTest, GarbageCollect_UserPresent) {
  GarbageCollectTest(SessionState::kUserPresent /*session_state*/);
}

TEST_F(EntryManagerTest, GenerateRules_NoUser) {
  GenerateRulesTest(SessionState::kNoUser /*session_state*/);
}

TEST_F(EntryManagerTest, GenerateRules_LockscreenShown) {
  GenerateRulesTest(SessionState::kLockscreenShown /*session_state*/);
}

TEST_F(EntryManagerTest, GenerateRules_UserPresent) {
  GenerateRulesTest(SessionState::kUserPresent /*session_state*/);
}

TEST_F(EntryManagerTest, HandleUdev_NoUser) {
  HandleUdevTest(SessionState::kNoUser /*session_state*/);
}

TEST_F(EntryManagerTest, HandleUdev_LockscreenShown) {
  HandleUdevTest(SessionState::kLockscreenShown /*session_state*/);
}

TEST_F(EntryManagerTest, HandleUdev_UserPresent) {
  HandleUdevTest(SessionState::kUserPresent /*session_state*/);
}

TEST_F(EntryManagerTest, HandleUserLogin_NoUser) {
  util_.RefreshDB(false /*include_user_db*/, true /*new_db*/);

  EXPECT_FALSE(util_.Get()->HandleUserLogin());
}

TEST_F(EntryManagerTest, HandleUserLogin_UserPresent) {
  util_.RefreshDB(false /*include_user_db*/, true /*new_db*/);

  EXPECT_TRUE(
      util_.Get()->HandleUdev(EntryManager::UdevAction::kAdd, kDefaultDevpath));

  util_.RefreshDB(true /*include_user_db*/, false /*new_db*/);

  EXPECT_TRUE(util_.GlobalDBContainsEntry(kDefaultDevpath, kDefaultRule));
  EXPECT_FALSE(util_.UserDBContainsEntry(kDefaultRule));

  EXPECT_TRUE(util_.Get()->HandleUserLogin());
  EXPECT_TRUE(util_.UserDBContainsEntry(kDefaultRule));
}

TEST_F(EntryManagerTest, HandleUserLogin_Guest) {
  util_.RefreshDB(false /*include_user_db*/, true /*new_db*/);
  util_.SetIsGuestSession(true);

  EXPECT_TRUE(util_.Get()->HandleUserLogin());
}

}  // namespace usb_bouncer
