// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/GSuiteDirectoryService.java
// public interface GSuiteDirectoryService {
// 
//     /**
//      * Retrieve all groups for a member.
//      *
//      * @param userKey The userKey can be the user's primary email address, the user's alias email address, a
//      * group's primary email address, a group's email alias, or the user's unique id.
//      * @return all groups for a member
//      */
//     GroupList getUserGroups(String userKey);
// 
// 
//     /**
//      * Read basic group information. This result does not contain group members. Call
//      * {@link #getGroupMembers(java.lang.String)} to obtain members.
//      *
//      * @param groupKey group identifier (email or ID)
//      * @return group info
//      * @throws eu.hlavki.identity.services.google.ResourceNotFoundException
//      */
//     GSuiteGroup getGroup(String groupKey) throws ResourceNotFoundException;
// 
// 
//     /**
//      * Read all members for group.
//      *
//      * @param groupKey group identifier (email or ID)
//      * @return group info and members
//      */
//     GroupMembership getGroupMembers(String groupKey) throws ResourceNotFoundException;
// 
// 
//     /**
//      * Read all GSuite groups. This result does not contain group members. Call
//      * {@link #getGroupMembers(java.lang.String)} to obtain members.
//      *
//      * @return all GSuite groups
//      */
//     GroupList getAllGroups();
// 
// 
//     /**
//      * Read members for all GSuite groups. Because it is very expesive operation, you can use cached values.
//      * Cache expires in 15 minutes. To use cache set useCache parameter to true.
//      *
//      *
//      * @return members for all GSuite groups. Key is group info object and value is membership
//      */
//     Map<GSuiteGroup, GroupMembership> getAllGroupMembership();
// 
// 
//     /**
//      * Retrieves a gsuite user from Directory API
//      *
//      * @param userKey Identifies the user in the API request. The value can be the user's primary email
//      * address, alias email address, or unique user ID.
//      * @return gsuite user
//      */
//     GSuiteUser getUser(String userKey);
// 
// 
//     /**
//      * Retrieves list of users or all users in a domain.
//      *
//      * @return list of gsuite users
//      */
//     GSuiteUsers getAllUsers();
// 
// 
//     void updateUserPassword(String userKey, String password) throws InvalidPasswordException;
// 
// 
//     String getDomainName();
// 
// 
//     String getImplicitGroup();
// 
// 
//     String completeGroupEmail(String groupName);
// }
// 
// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/InvalidPasswordException.java
// public class InvalidPasswordException extends Exception {
// 
//     private static final long serialVersionUID = 2712920621905135028L;
// 
//     public InvalidPasswordException() {
//         super();
//     }
// 
// 
//     public InvalidPasswordException(String message) {
//         super(message);
//     }
// 
// 
//     public InvalidPasswordException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
// 
//     public InvalidPasswordException(Throwable cause) {
//         super(cause);
//     }
// }
// 
// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/ResourceNotFoundException.java
// public class ResourceNotFoundException extends RuntimeException {
// 
//     private static final long serialVersionUID = 1L;
// 
// 
//     public ResourceNotFoundException() {
//     }
// 
// 
//     public ResourceNotFoundException(String message) {
//         super(message);
//     }
// 
// 
//     public ResourceNotFoundException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
// 
//     public ResourceNotFoundException(Throwable cause) {
//         super(cause);
//     }
// 
// 
//     public ResourceNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// }
// 
// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/config/Configuration.java
// public interface Configuration {
// 
//     String getGSuiteDomain();
// 
// 
//     String getGSuiteImplicitGroup();
// 
// 
//     boolean isSetGSuiteImplicitGroup();
// 
// 
//     String getServiceAccountEmail();
// 
// 
//     String getServiceAccountSubject();
// 
// 
//     Set<String> getServiceAccountScopes();
// 
// 
//     PrivateKey readServiceAccountKey() throws NoPrivateKeyException;
// 
// 
//     void setServiceAccount(String clientEmail, String privateKey, String subject, String tokenUri);
// 
// 
//     void resetServiceAccount();
// 
// 
//     String getServiceAccountTokenUri();
// 
// 
//     long getServiceAccountTokenLifetime();
// 
// 
//     String getPushServiceHostname();
// 
// 
//     void setPushServiceHostname(String hostname);
// 
// 
//     File getPushChannelFile();
// 
// 
//     boolean isPushEnabled();
// 
// 
//     void setPushEnabled(boolean value);
// 
// 
//     Duration getPushRefreshInterval();
// }


import eu.hlavki.identity.services.google.GSuiteDirectoryService;
import eu.hlavki.identity.services.google.InvalidPasswordException;
import eu.hlavki.identity.services.google.ResourceNotFoundException;
import eu.hlavki.identity.services.google.config.Configuration;
import eu.hlavki.identity.services.google.model.*;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
package eu.hlavki.identity.services.google.impl;


public class GSuiteDirectoryServiceImpl implements GSuiteDirectoryService {

    private static final Logger LOG = LoggerFactory.getLogger(GSuiteDirectoryServiceImpl.class);

    private final TokenCache tokenCache;
    private final WebClient directoryApiClient;
// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/GSuiteDirectoryService.java
// public interface GSuiteDirectoryService {
// 
//     /**
//      * Retrieve all groups for a member.
//      *
//      * @param userKey The userKey can be the user's primary email address, the user's alias email address, a
//      * group's primary email address, a group's email alias, or the user's unique id.
//      * @return all groups for a member
//      */
//     GroupList getUserGroups(String userKey);
// 
// 
//     /**
//      * Read basic group information. This result does not contain group members. Call
//      * {@link #getGroupMembers(java.lang.String)} to obtain members.
//      *
//      * @param groupKey group identifier (email or ID)
//      * @return group info
//      * @throws eu.hlavki.identity.services.google.ResourceNotFoundException
//      */
//     GSuiteGroup getGroup(String groupKey) throws ResourceNotFoundException;
// 
// 
//     /**
//      * Read all members for group.
//      *
//      * @param groupKey group identifier (email or ID)
//      * @return group info and members
//      */
//     GroupMembership getGroupMembers(String groupKey) throws ResourceNotFoundException;
// 
// 
//     /**
//      * Read all GSuite groups. This result does not contain group members. Call
//      * {@link #getGroupMembers(java.lang.String)} to obtain members.
//      *
//      * @return all GSuite groups
//      */
//     GroupList getAllGroups();
// 
// 
//     /**
//      * Read members for all GSuite groups. Because it is very expesive operation, you can use cached values.
//      * Cache expires in 15 minutes. To use cache set useCache parameter to true.
//      *
//      *
//      * @return members for all GSuite groups. Key is group info object and value is membership
//      */
//     Map<GSuiteGroup, GroupMembership> getAllGroupMembership();
// 
// 
//     /**
//      * Retrieves a gsuite user from Directory API
//      *
//      * @param userKey Identifies the user in the API request. The value can be the user's primary email
//      * address, alias email address, or unique user ID.
//      * @return gsuite user
//      */
//     GSuiteUser getUser(String userKey);
// 
// 
//     /**
//      * Retrieves list of users or all users in a domain.
//      *
//      * @return list of gsuite users
//      */
//     GSuiteUsers getAllUsers();
// 
// 
//     void updateUserPassword(String userKey, String password) throws InvalidPasswordException;
// 
// 
//     String getDomainName();
// 
// 
//     String getImplicitGroup();
// 
// 
//     String completeGroupEmail(String groupName);
// }
// 
// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/InvalidPasswordException.java
// public class InvalidPasswordException extends Exception {
// 
//     private static final long serialVersionUID = 2712920621905135028L;
// 
//     public InvalidPasswordException() {
//         super();
//     }
// 
// 
//     public InvalidPasswordException(String message) {
//         super(message);
//     }
// 
// 
//     public InvalidPasswordException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
// 
//     public InvalidPasswordException(Throwable cause) {
//         super(cause);
//     }
// }
// 
// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/ResourceNotFoundException.java
// public class ResourceNotFoundException extends RuntimeException {
// 
//     private static final long serialVersionUID = 1L;
// 
// 
//     public ResourceNotFoundException() {
//     }
// 
// 
//     public ResourceNotFoundException(String message) {
//         super(message);
//     }
// 
// 
//     public ResourceNotFoundException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
// 
//     public ResourceNotFoundException(Throwable cause) {
//         super(cause);
//     }
// 
// 
//     public ResourceNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// }
// 
// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/config/Configuration.java
// public interface Configuration {
// 
//     String getGSuiteDomain();
// 
// 
//     String getGSuiteImplicitGroup();
// 
// 
//     boolean isSetGSuiteImplicitGroup();
// 
// 
//     String getServiceAccountEmail();
// 
// 
//     String getServiceAccountSubject();
// 
// 
//     Set<String> getServiceAccountScopes();
// 
// 
//     PrivateKey readServiceAccountKey() throws NoPrivateKeyException;
// 
// 
//     void setServiceAccount(String clientEmail, String privateKey, String subject, String tokenUri);
// 
// 
//     void resetServiceAccount();
// 
// 
//     String getServiceAccountTokenUri();
// 
// 
//     long getServiceAccountTokenLifetime();
// 
// 
//     String getPushServiceHostname();
// 
// 
//     void setPushServiceHostname(String hostname);
// 
// 
//     File getPushChannelFile();
// 
// 
//     boolean isPushEnabled();
// 
// 
//     void setPushEnabled(boolean value);
// 
// 
//     Duration getPushRefreshInterval();
// }


// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/impl/GSuiteDirectoryServiceImpl.java
import eu.hlavki.identity.services.google.GSuiteDirectoryService;
import eu.hlavki.identity.services.google.InvalidPasswordException;
import eu.hlavki.identity.services.google.ResourceNotFoundException;
import eu.hlavki.identity.services.google.config.Configuration;
import eu.hlavki.identity.services.google.model.*;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.Response;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

package eu.hlavki.identity.services.google.impl;


public class GSuiteDirectoryServiceImpl implements GSuiteDirectoryService {

    private static final Logger LOG = LoggerFactory.getLogger(GSuiteDirectoryServiceImpl.class);

    private final TokenCache tokenCache;
    private final WebClient directoryApiClient;
    private final Configuration config;