class Acl {

  public static PrincipalType getPrincipalType(Principal p) {
    checkNotNull(p, "Principal can not be null");
    boolean isGSuitePrincipal = Objects.nonNull(p.getGsuitePrincipal());
    boolean isGSuiteUser =
        isGSuitePrincipal && !Strings.isNullOrEmpty(p.getGsuitePrincipal().getGsuiteUserEmail());
    boolean isGSuiteGroup =
        isGSuitePrincipal && !Strings.isNullOrEmpty(p.getGsuitePrincipal().getGsuiteGroupEmail());
    boolean isGSuiteDomain =
        isGSuitePrincipal
            && Objects.nonNull(p.getGsuitePrincipal().getGsuiteDomain())
            && p.getGsuitePrincipal().getGsuiteDomain();
    boolean isUserPrincipal = !Strings.isNullOrEmpty(p.getUserResourceName());
    boolean isGroupPrincipal = !Strings.isNullOrEmpty(p.getGroupResourceName());
    if (isGSuitePrincipal) {
      checkArgument(!isUserPrincipal && !isGroupPrincipal, "Invalid principal");
      if (isGSuiteGroup) {
        checkArgument(!isGSuiteDomain && !isGSuiteUser, "Invalid principal");
        return PrincipalType.GSUITE_GROUP;
      } else if (isGSuiteUser) {
        checkArgument(!isGSuiteDomain, "Invalid principal");
        return PrincipalType.GSUITE_USER;
      } else {
        checkArgument(isGSuiteDomain, "Invalid principal");
        return PrincipalType.GSUITE_DOMAIN;
      }
    } else if (isUserPrincipal) {
      checkArgument(!isGroupPrincipal, "Invalid principal");
      return PrincipalType.USER;
    } else {
      checkArgument(isGroupPrincipal, "Invalid principal");
      return PrincipalType.GROUP;
    }
  }

  private  Acl(Builder builder);

}