/*
 * Copyright (C) 2018 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 <unistd.h>

#include <gtest/gtest.h>

#include <android-base/file.h>

#if defined(__BIONIC__)
#include "../libc/bionic/grp_pwd_file.cpp"

template <typename T>
class FileUnmapper {
 public:
  explicit FileUnmapper(T& file) : file_(file) {
  }
  ~FileUnmapper() {
    file_.Unmap();
  }

 private:
  T& file_;
};

void FindAndCheckPasswdEntry(PasswdFile* file, const char* name, uid_t uid, gid_t gid,
                             const char* dir, const char* shell) {
  passwd_state_t name_passwd_state;
  ASSERT_TRUE(file->FindByName(name, &name_passwd_state)) << name;

  passwd& name_passwd = name_passwd_state.passwd_;
  EXPECT_STREQ(name, name_passwd.pw_name);
  EXPECT_EQ(nullptr, name_passwd.pw_passwd);
  EXPECT_EQ(uid, name_passwd.pw_uid);
  EXPECT_EQ(gid, name_passwd.pw_gid);
  EXPECT_EQ(nullptr, name_passwd.pw_gecos);
  EXPECT_STREQ(dir, name_passwd.pw_dir);
  EXPECT_STREQ(shell, name_passwd.pw_shell);

  passwd_state_t id_passwd_state;
  ASSERT_TRUE(file->FindById(uid, &id_passwd_state)) << uid;

  passwd& id_passwd = id_passwd_state.passwd_;
  EXPECT_STREQ(name, id_passwd.pw_name);
  EXPECT_EQ(nullptr, id_passwd.pw_passwd);
  EXPECT_EQ(uid, id_passwd.pw_uid);
  EXPECT_EQ(gid, id_passwd.pw_gid);
  EXPECT_EQ(nullptr, id_passwd.pw_gecos);
  EXPECT_STREQ(dir, id_passwd.pw_dir);
  EXPECT_STREQ(shell, id_passwd.pw_shell);
}

void FindAndCheckGroupEntry(GroupFile* file, const char* name, gid_t gid) {
  group_state_t name_group_state;
  ASSERT_TRUE(file->FindByName(name, &name_group_state)) << name;

  group& name_group = name_group_state.group_;
  EXPECT_STREQ(name, name_group.gr_name);
  EXPECT_EQ(nullptr, name_group.gr_passwd);
  EXPECT_EQ(gid, name_group.gr_gid);
  EXPECT_EQ(name_group.gr_name, name_group.gr_mem[0]);
  EXPECT_EQ(nullptr, name_group.gr_mem[1]);

  group_state_t id_group_state;
  ASSERT_TRUE(file->FindById(gid, &id_group_state)) << gid;

  group& id_group = id_group_state.group_;
  EXPECT_STREQ(name, id_group.gr_name);
  EXPECT_EQ(nullptr, id_group.gr_passwd);
  EXPECT_EQ(gid, id_group.gr_gid);
  EXPECT_EQ(id_group.gr_name, id_group.gr_mem[0]);
  EXPECT_EQ(nullptr, id_group.gr_mem[1]);
}

#endif  // __BIONIC__

TEST(grp_pwd_file, passwd_file_one_entry) {
#if defined(__BIONIC__)
  TemporaryFile file;
  ASSERT_NE(-1, file.fd);
  static const char test_string[] = "name:password:1:2:user_info:dir:shell\n";
  write(file.fd, test_string, sizeof(test_string) - 1);

  PasswdFile passwd_file(file.path, nullptr);
  FileUnmapper unmapper(passwd_file);

  FindAndCheckPasswdEntry(&passwd_file, "name", 1, 2, "dir", "shell");

  EXPECT_FALSE(passwd_file.FindByName("not_name", nullptr));
  EXPECT_FALSE(passwd_file.FindById(3, nullptr));

#else   // __BIONIC__
  GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif  // __BIONIC__
}

TEST(grp_pwd_file, group_file_one_entry) {
#if defined(__BIONIC__)
  TemporaryFile file;
  ASSERT_NE(-1, file.fd);
  static const char test_string[] = "name:password:1:one,two,three\n";
  write(file.fd, test_string, sizeof(test_string) - 1);

  GroupFile group_file(file.path, nullptr);
  FileUnmapper unmapper(group_file);

  FindAndCheckGroupEntry(&group_file, "name", 1);

  EXPECT_FALSE(group_file.FindByName("not_name", nullptr));
  EXPECT_FALSE(group_file.FindById(3, nullptr));

#else   // __BIONIC__
  GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif  // __BIONIC__
}

TEST(grp_pwd_file, passwd_file_many_entries) {
#if defined(__BIONIC__)
  TemporaryFile file;
  ASSERT_NE(-1, file.fd);
  static const char test_string[] =
      "first:x:1:2::dir:shell\n"
      "abc1::3:4::def:abc\n"
      "abc2::5:4:abc::abc\n"
      "abc3::7:4:abc:def:\n"
      "abc4::9:4:::abc\n"
      "abc5::11:4:abc:def:abc\n"
      "middle-ish::13:4::/:/system/bin/sh\n"
      "abc7::15:4:abc::\n"
      "abc8::17:4:::\n"
      "abc9::19:4:abc:def:abc\n"
      "abc10::21:4:abc:def:abc\n"
      "abc11::23:4:abc:def:abc\n"
      "abc12::25:4:abc:def:abc\n"
      "abc13::27:4:abc:def:abc\n"
      "last::29:4::last_user_dir:last_user_shell\n";

  write(file.fd, test_string, sizeof(test_string) - 1);

  PasswdFile passwd_file(file.path, nullptr);
  FileUnmapper unmapper(passwd_file);

  FindAndCheckPasswdEntry(&passwd_file, "first", 1, 2, "dir", "shell");
  FindAndCheckPasswdEntry(&passwd_file, "middle-ish", 13, 4, "/", "/system/bin/sh");
  FindAndCheckPasswdEntry(&passwd_file, "last", 29, 4, "last_user_dir", "last_user_shell");

  EXPECT_FALSE(passwd_file.FindByName("not_name", nullptr));
  EXPECT_FALSE(passwd_file.FindById(50, nullptr));

#else   // __BIONIC__
  GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif  // __BIONIC__
}

TEST(grp_pwd_file, group_file_many_entries) {
#if defined(__BIONIC__)
  TemporaryFile file;
  ASSERT_NE(-1, file.fd);
  static const char test_string[] =
      "first:password:1:one,two,three\n"
      "abc:def:2:group1,group2,group3\n"
      "abc:def:3:\n"
      "abc:def:4:\n"
      "abc:def:5:\n"
      "middle-ish:def_a_password_that_is_over_32_characters_long:6:\n"
      "abc:def:7:\n"
      "abc:def:8:\n"
      "abc:def:20:\n"
      "abc:def:25:\n"
      "abc:def:27:\n"
      "abc:def:52:\n"
      "last::800:\n";

  write(file.fd, test_string, sizeof(test_string) - 1);

  GroupFile group_file(file.path, nullptr);
  FileUnmapper unmapper(group_file);

  FindAndCheckGroupEntry(&group_file, "first", 1);
  FindAndCheckGroupEntry(&group_file, "middle-ish", 6);
  FindAndCheckGroupEntry(&group_file, "last", 800);

  EXPECT_FALSE(group_file.FindByName("not_name", nullptr));
  EXPECT_FALSE(group_file.FindById(799, nullptr));

#else   // __BIONIC__
  GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif  // __BIONIC__
}

TEST(grp_pwd_file, passwd_file_required_prefix) {
#if defined(__BIONIC__)
  TemporaryFile file;
  ASSERT_NE(-1, file.fd);
  static const char test_string[] =
      "name:password:1:2:user_info:dir:shell\n"
      "vendor_name:password:3:4:user_info:dir:shell\n";
  write(file.fd, test_string, sizeof(test_string) - 1);

  PasswdFile passwd_file(file.path, "vendor_");
  FileUnmapper unmapper(passwd_file);

  EXPECT_FALSE(passwd_file.FindByName("name", nullptr));
  EXPECT_FALSE(passwd_file.FindById(1, nullptr));

  FindAndCheckPasswdEntry(&passwd_file, "vendor_name", 3, 4, "dir", "shell");

#else   // __BIONIC__
  GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif  // __BIONIC__
}

TEST(grp_pwd_file, group_file_required_prefix) {
#if defined(__BIONIC__)
  TemporaryFile file;
  ASSERT_NE(-1, file.fd);
  static const char test_string[] =
      "name:password:1:one,two,three\n"
      "vendor_name:password:2:one,two,three\n";
  write(file.fd, test_string, sizeof(test_string) - 1);

  GroupFile group_file(file.path, "vendor_");
  FileUnmapper unmapper(group_file);

  EXPECT_FALSE(group_file.FindByName("name", nullptr));
  EXPECT_FALSE(group_file.FindById(1, nullptr));

  FindAndCheckGroupEntry(&group_file, "vendor_name", 2);

#else   // __BIONIC__
  GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif  // __BIONIC__
}
