// Path: send-notification/src/main/java/fr/jcgay/notification/configuration/ChosenNotifiers.java
// @AutoValue
// public abstract class ChosenNotifiers {
// 
//     private static final String SEPARATOR = ",";
// 
//     public abstract String primary();
// 
//     public abstract Set<String> secondary();
// 
//     ChosenNotifiers() {
//         // prevent external subclasses
//     }
// 
//     public static ChosenNotifiers from(String notifier) {
//         checkNotNull(notifier);
// 
//         if (!notifier.contains(SEPARATOR)) {
//             return new AutoValue_ChosenNotifiers(notifier, Collections.emptySet());
//         }
// 
//         String[] notifiers = notifier.split(SEPARATOR);
//         Set<String> secondary = new LinkedHashSet<>(asList(notifiers).subList(1, notifiers.length));
//         return new AutoValue_ChosenNotifiers(notifiers[0], secondary);
//     }
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/configuration/ConfigurationReader.java
// public class ConfigurationReader {
// 
//     private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationReader.class);
// 
//     private final Properties properties;
//     private final URL location;
// 
//     private ConfigurationReader(Properties properties) {
//         this(properties, null);
//     }
// 
//     public ConfigurationReader(Properties configuration, URL location) {
//         this.properties = configuration;
//         this.location = location;
//     }
// 
//     public static ConfigurationReader atPath(String path) {
//         try {
//             return atUrl(new File(path).toURI().toURL());
//         } catch (MalformedURLException e) {
//             LOGGER.debug("URL built for path [{}] is malformed will use default configuration.", path, e);
//             return new ConfigurationReader(new Properties());
//         }
//     }
// 
//     public static ConfigurationReader atUrl(URL url) {
//         Properties configuration = new Properties();
//         try {
//             configuration.load(url.openStream());
//         } catch (IOException e) {
//             LOGGER.debug("Cannot read configuration at [{}], will use default one.", url, e);
//         }
//         return new ConfigurationReader(configuration, url);
//     }
// 
//     public Properties get() {
//         LOGGER.debug("Notification configuration read from {} is: {}.", location, properties);
//         return properties;
//     }
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/configuration/OperatingSystem.java
// public class OperatingSystem {
// 
//     private final String currentOs;
// 
//     public OperatingSystem() {
//         currentOs = System.getProperty("os.name").toLowerCase();
//     }
// 
//     public OperatingSystem(String currentOs) {
//         this.currentOs = currentOs.toLowerCase();
//     }
// 
//     public boolean isMac() {
//         return currentOs.contains("mac");
//     }
// 
//     public boolean isWindows() {
//         return currentOs.contains("win");
//     }
// 
//     @Override
//     public String toString() {
//         return "OperatingSystem{" +
//                 "currentOs='" + currentOs + '\'' +
//                 '}';
//     }
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/notifier/DoNothingNotifier.java
// public class DoNothingNotifier implements DiscoverableNotifier {
// 
//     private static final DoNothingNotifier INSTANCE = new DoNothingNotifier();
// 
//     public static DoNothingNotifier doNothing() {
//         return INSTANCE;
//     }
// 
//     private DoNothingNotifier() {
//     }
// 
//     @Override
//     public Notifier init() {
//         return this;
//     }
// 
//     @Override
//     public void send(Notification notification) {
//         // do nothing
//     }
// 
//     @Override
//     public void close() {
//         // do nothing
//     }
// 
//     @Override
//     public boolean isPersistent() {
//         return false;
//     }
// 
//     @Override
//     public boolean tryInit() {
//         return true;
//     }
// }


import com.google.common.annotations.VisibleForTesting;
import fr.jcgay.notification.configuration.ChosenNotifiers;
import fr.jcgay.notification.configuration.ConfigurationReader;
import fr.jcgay.notification.configuration.OperatingSystem;
import fr.jcgay.notification.notifier.DoNothingNotifier;
import org.slf4j.Logger;
import java.util.Properties;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
package fr.jcgay.notification;




/**
 * Fluent builder to create a {@link fr.jcgay.notification.Notifier}. <br>
 *
 * You'll need a configuration file (by default: {@code {user.home}/.send-notification}
 * to select and configure a {@link fr.jcgay.notification.Notifier}. <br>
 * This file must be property based (example):
 * <pre>{@code
 * notifier.implementation = pushbullet
 * notifier.message.short = true
 * notifier.pushbullet.apikey = 1234
 * }</pre>
 *
 * Then to create a notifier you can use:
 * <pre>{@code
 * Notifier notifier = new SendNotification()
 *  .setApplication(application)
 *  .initNotifier();
 * }</pre>
 */
public class SendNotification {

    private static final Logger LOGGER = getLogger(SendNotification.class);

    private final NotifierProvider provider;

// Path: send-notification/src/main/java/fr/jcgay/notification/configuration/ChosenNotifiers.java
// @AutoValue
// public abstract class ChosenNotifiers {
// 
//     private static final String SEPARATOR = ",";
// 
//     public abstract String primary();
// 
//     public abstract Set<String> secondary();
// 
//     ChosenNotifiers() {
//         // prevent external subclasses
//     }
// 
//     public static ChosenNotifiers from(String notifier) {
//         checkNotNull(notifier);
// 
//         if (!notifier.contains(SEPARATOR)) {
//             return new AutoValue_ChosenNotifiers(notifier, Collections.emptySet());
//         }
// 
//         String[] notifiers = notifier.split(SEPARATOR);
//         Set<String> secondary = new LinkedHashSet<>(asList(notifiers).subList(1, notifiers.length));
//         return new AutoValue_ChosenNotifiers(notifiers[0], secondary);
//     }
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/configuration/ConfigurationReader.java
// public class ConfigurationReader {
// 
//     private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationReader.class);
// 
//     private final Properties properties;
//     private final URL location;
// 
//     private ConfigurationReader(Properties properties) {
//         this(properties, null);
//     }
// 
//     public ConfigurationReader(Properties configuration, URL location) {
//         this.properties = configuration;
//         this.location = location;
//     }
// 
//     public static ConfigurationReader atPath(String path) {
//         try {
//             return atUrl(new File(path).toURI().toURL());
//         } catch (MalformedURLException e) {
//             LOGGER.debug("URL built for path [{}] is malformed will use default configuration.", path, e);
//             return new ConfigurationReader(new Properties());
//         }
//     }
// 
//     public static ConfigurationReader atUrl(URL url) {
//         Properties configuration = new Properties();
//         try {
//             configuration.load(url.openStream());
//         } catch (IOException e) {
//             LOGGER.debug("Cannot read configuration at [{}], will use default one.", url, e);
//         }
//         return new ConfigurationReader(configuration, url);
//     }
// 
//     public Properties get() {
//         LOGGER.debug("Notification configuration read from {} is: {}.", location, properties);
//         return properties;
//     }
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/configuration/OperatingSystem.java
// public class OperatingSystem {
// 
//     private final String currentOs;
// 
//     public OperatingSystem() {
//         currentOs = System.getProperty("os.name").toLowerCase();
//     }
// 
//     public OperatingSystem(String currentOs) {
//         this.currentOs = currentOs.toLowerCase();
//     }
// 
//     public boolean isMac() {
//         return currentOs.contains("mac");
//     }
// 
//     public boolean isWindows() {
//         return currentOs.contains("win");
//     }
// 
//     @Override
//     public String toString() {
//         return "OperatingSystem{" +
//                 "currentOs='" + currentOs + '\'' +
//                 '}';
//     }
// }
// 
// Path: send-notification/src/main/java/fr/jcgay/notification/notifier/DoNothingNotifier.java
// public class DoNothingNotifier implements DiscoverableNotifier {
// 
//     private static final DoNothingNotifier INSTANCE = new DoNothingNotifier();
// 
//     public static DoNothingNotifier doNothing() {
//         return INSTANCE;
//     }
// 
//     private DoNothingNotifier() {
//     }
// 
//     @Override
//     public Notifier init() {
//         return this;
//     }
// 
//     @Override
//     public void send(Notification notification) {
//         // do nothing
//     }
// 
//     @Override
//     public void close() {
//         // do nothing
//     }
// 
//     @Override
//     public boolean isPersistent() {
//         return false;
//     }
// 
//     @Override
//     public boolean tryInit() {
//         return true;
//     }
// }


// Path: send-notification/src/main/java/fr/jcgay/notification/SendNotification.java
import com.google.common.annotations.VisibleForTesting;
import fr.jcgay.notification.configuration.ChosenNotifiers;
import fr.jcgay.notification.configuration.ConfigurationReader;
import fr.jcgay.notification.configuration.OperatingSystem;
import fr.jcgay.notification.notifier.DoNothingNotifier;
import org.slf4j.Logger;
import java.util.Properties;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

package fr.jcgay.notification;




/**
 * Fluent builder to create a {@link fr.jcgay.notification.Notifier}. <br>
 *
 * You'll need a configuration file (by default: {@code {user.home}/.send-notification}
 * to select and configure a {@link fr.jcgay.notification.Notifier}. <br>
 * This file must be property based (example):
 * <pre>{@code
 * notifier.implementation = pushbullet
 * notifier.message.short = true
 * notifier.pushbullet.apikey = 1234
 * }</pre>
 *
 * Then to create a notifier you can use:
 * <pre>{@code
 * Notifier notifier = new SendNotification()
 *  .setApplication(application)
 *  .initNotifier();
 * }</pre>
 */
public class SendNotification {

    private static final Logger LOGGER = getLogger(SendNotification.class);

    private final NotifierProvider provider;

    private ConfigurationReader configuration;