// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/PushNotificationService.java
// public interface PushNotificationService {
// 
//     /**
//      * Enable push notification. Set hostname for push service
//      *
//      * @param hostname
//      */
//     void enablePushNotifications(String hostname);
// 
// 
//     void disablePushNotifications();
// 
// 
//     void refreshPushNotifications();
// 
// 
//     void stopPushChannel(String id, String resourceId);
// 
// 
//     boolean isEnabled();
// }
// 
// 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/model/PushChannel.java
// @Getter
// @Setter
// @EqualsAndHashCode(onlyExplicitlyIncluded = true)
// @ToString
// @NoArgsConstructor
// @XmlRootElement(name = "channel")
// @XmlAccessorType(XmlAccessType.FIELD)
// public class PushChannel {
// 
//     @EqualsAndHashCode.Include
//     @XmlElement
//     private String id;
//     @XmlElement
//     private String kind;
//     @XmlElement
//     private String resourceId;
//     @XmlElement
//     private String resourceUri;
//     @XmlElement
//     private String token;
//     @XmlElement
//     private Long expiration;
// 
// 
//     public boolean expiresIn(Duration bestBefore) {
//         return expiration - System.currentTimeMillis() < bestBefore.toMillis();
//     }
// }
// 
// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/model/StartPushChannel.java
// @Data
// @XmlRootElement
// public class StartPushChannel {
// 
//     private String id;
//     private String type = "web_hook";
//     private String address;
//     private String token;
//     private long expiration;
//     private Params params;
// 
// 
//     public StartPushChannel() {
//         id = UUID.randomUUID().toString();
//     }
// 
// 
//     public StartPushChannel(String address, Duration duration) {
//         this();
//         this.address = address;
//         this.expiration = System.currentTimeMillis() + duration.toMillis();
// //        this.params = new Params();
// //        this.params.ttl = duration.getSeconds();
//     }
// 
//     @Data
//     @NoArgsConstructor
//     @AllArgsConstructor
//     public static class Params {
// 
//         private long ttl;
//     }
// }
// 
// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/model/StopPushChannel.java
// @Getter
// @Setter
// @NoArgsConstructor
// @AllArgsConstructor
// @XmlRootElement
// public class StopPushChannel {
// 
//     private String id;
//     private String resourceId;
// 
// 
//     public StopPushChannel(PushChannel watching) {
//         this.id = watching.getId();
//         this.resourceId = watching.getResourceId();
//     }
// }


import eu.hlavki.identity.services.google.PushNotificationService;
import eu.hlavki.identity.services.google.config.Configuration;
import eu.hlavki.identity.services.google.model.PushChannel;
import eu.hlavki.identity.services.google.model.StartPushChannel;
import eu.hlavki.identity.services.google.model.StopPushChannel;
import java.io.File;
import java.time.Duration;
import java.util.Optional;
import static java.util.Optional.empty;
import javax.ws.rs.ClientErrorException;
import javax.ws.rs.core.Response;
import static javax.ws.rs.core.Response.Status.*;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
import org.apache.karaf.scheduler.ScheduleOptions;
import org.apache.karaf.scheduler.Scheduler;
import org.apache.karaf.scheduler.SchedulerError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
package eu.hlavki.identity.services.google.impl;


public class PushNotificationServiceImpl implements PushNotificationService {

    private static final Logger log = LoggerFactory.getLogger(PushNotificationServiceImpl.class);

    private static final String PUSH_SCHEDULER_JOB = "PushNotificationJob";

    private Optional<PushChannel> channel = empty();

// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/PushNotificationService.java
// public interface PushNotificationService {
// 
//     /**
//      * Enable push notification. Set hostname for push service
//      *
//      * @param hostname
//      */
//     void enablePushNotifications(String hostname);
// 
// 
//     void disablePushNotifications();
// 
// 
//     void refreshPushNotifications();
// 
// 
//     void stopPushChannel(String id, String resourceId);
// 
// 
//     boolean isEnabled();
// }
// 
// 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/model/PushChannel.java
// @Getter
// @Setter
// @EqualsAndHashCode(onlyExplicitlyIncluded = true)
// @ToString
// @NoArgsConstructor
// @XmlRootElement(name = "channel")
// @XmlAccessorType(XmlAccessType.FIELD)
// public class PushChannel {
// 
//     @EqualsAndHashCode.Include
//     @XmlElement
//     private String id;
//     @XmlElement
//     private String kind;
//     @XmlElement
//     private String resourceId;
//     @XmlElement
//     private String resourceUri;
//     @XmlElement
//     private String token;
//     @XmlElement
//     private Long expiration;
// 
// 
//     public boolean expiresIn(Duration bestBefore) {
//         return expiration - System.currentTimeMillis() < bestBefore.toMillis();
//     }
// }
// 
// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/model/StartPushChannel.java
// @Data
// @XmlRootElement
// public class StartPushChannel {
// 
//     private String id;
//     private String type = "web_hook";
//     private String address;
//     private String token;
//     private long expiration;
//     private Params params;
// 
// 
//     public StartPushChannel() {
//         id = UUID.randomUUID().toString();
//     }
// 
// 
//     public StartPushChannel(String address, Duration duration) {
//         this();
//         this.address = address;
//         this.expiration = System.currentTimeMillis() + duration.toMillis();
// //        this.params = new Params();
// //        this.params.ttl = duration.getSeconds();
//     }
// 
//     @Data
//     @NoArgsConstructor
//     @AllArgsConstructor
//     public static class Params {
// 
//         private long ttl;
//     }
// }
// 
// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/model/StopPushChannel.java
// @Getter
// @Setter
// @NoArgsConstructor
// @AllArgsConstructor
// @XmlRootElement
// public class StopPushChannel {
// 
//     private String id;
//     private String resourceId;
// 
// 
//     public StopPushChannel(PushChannel watching) {
//         this.id = watching.getId();
//         this.resourceId = watching.getResourceId();
//     }
// }


// Path: services/google/api/src/main/java/eu/hlavki/identity/services/google/impl/PushNotificationServiceImpl.java
import eu.hlavki.identity.services.google.PushNotificationService;
import eu.hlavki.identity.services.google.config.Configuration;
import eu.hlavki.identity.services.google.model.PushChannel;
import eu.hlavki.identity.services.google.model.StartPushChannel;
import eu.hlavki.identity.services.google.model.StopPushChannel;
import java.io.File;
import java.time.Duration;
import java.util.Optional;
import static java.util.Optional.empty;
import javax.ws.rs.ClientErrorException;
import javax.ws.rs.core.Response;
import static javax.ws.rs.core.Response.Status.*;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
import org.apache.karaf.scheduler.ScheduleOptions;
import org.apache.karaf.scheduler.Scheduler;
import org.apache.karaf.scheduler.SchedulerError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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


public class PushNotificationServiceImpl implements PushNotificationService {

    private static final Logger log = LoggerFactory.getLogger(PushNotificationServiceImpl.class);

    private static final String PUSH_SCHEDULER_JOB = "PushNotificationJob";

    private Optional<PushChannel> channel = empty();

    private final Configuration config;