/*
 * 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_SKIP() << "bionic-only test";
#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_SKIP() << "bionic-only test";
#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_SKIP() << "bionic-only test";
#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_SKIP() << "bionic-only test";
#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_SKIP() << "bionic-only test";
#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_SKIP() << "bionic-only test";
#endif  // __BIONIC__
}
