/*
 * 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 "TemporaryFile.h"

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

template <typename T>
class FileUnmapper {
 public:
  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.filename, 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.filename, 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.filename, 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.filename, 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.filename, "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.filename, "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__
}
