// Path: src/main/java/no/asgari/civilization/server/model/Chat.java
// @Data
// @JsonRootName("chat")
// @NoArgsConstructor
// @JsonIgnoreProperties(ignoreUnknown = true)
// public class Chat {
//     public static final String COL_NAME = "chat";
//     public static final String PBFID = "pbfId";
// 
//     @Id
//     @ObjectId
//     private String id;
// 
//     private String pbfId;
// 
//     @NotNull
//     private String username;
// 
//     @NotEmpty
//     private String message;
// 
//     @JsonSerialize(using = LocalDateTimeSerializer.class)
//     @JsonDeserialize(using = LocalDateTimeDeserializer.class)
//     private LocalDateTime created = LocalDateTime.now();
// 
//     @JsonIgnore
//     public long getCreatedInMillis() {
//         return created.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
//     }
// }
// 
// Path: src/main/java/no/asgari/civilization/server/model/Player.java
// @Data
// @JsonRootName("player")
// @NoArgsConstructor
// @JsonIgnoreProperties(ignoreUnknown = true)
// public class Player {
//     @JsonIgnore
//     public static final String COL_NAME = "player";
//     @JsonIgnore
//     public static final String USERNAME = "username";
//     @JsonIgnore
//     public static final String EMAIL = "email";
// 
//     @ObjectId
//     @Id
//     private String id;
// 
//     @NotBlank
//     //Unique
//     private String username;
// 
//     @Email
//     private String email;
// 
//     private boolean disableEmail = false;
// 
//     @NotBlank
//     private String password;
// 
//     private String newPassword;
// 
//     @JsonSerialize(using = LocalDateTimeSerializer.class)
//     @JsonDeserialize(using = LocalDateTimeDeserializer.class)
//     private LocalDateTime emailSent;
// 
//     /**
//      * Set of unique active games This may be reduntant as it can be calculated by looping through all pbfs.players and finding match.
//      */
//     private Set<String> gameIds = new HashSet<>();
// 
//     @JsonIgnore
//     public Optional<LocalDateTime> getIfEmailSent() {
//         return Optional.ofNullable(emailSent);
//     }
// }


import com.codahale.metrics.MetricRegistry;
import com.google.common.base.Strings;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheBuilderSpec;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.mongodb.*;
import io.dropwizard.Application;
import io.dropwizard.assets.AssetsBundle;
import io.dropwizard.auth.basic.BasicCredentials;
import io.dropwizard.java8.Java8Bundle;
import io.dropwizard.java8.auth.AuthFactory;
import io.dropwizard.java8.auth.CachingAuthenticator;
import io.dropwizard.java8.auth.basic.BasicAuthFactory;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import lombok.extern.log4j.Log4j;
import no.asgari.civilization.server.model.Chat;
import no.asgari.civilization.server.model.Player;
import no.asgari.civilization.server.resource.*;
import org.eclipse.jetty.servlets.CrossOriginFilter;
import org.glassfish.hk2.utilities.Binder;
import org.mongojack.JacksonDBCollection;
import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import static org.eclipse.jetty.servlets.CrossOriginFilter.*;
/*
 * Copyright (c) 2015 Shervin Asgari
 * 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.
 */

package no.asgari.civilization.server.application;




@Log4j
@SuppressWarnings("unchecked")
public class CivilizationApplication extends Application<CivilizationConfiguration> {

    public static void main(String[] args) throws Exception {
        if (args == null || args.length == 0) {
            new CivilizationApplication().run("server", "src/main/resources/config.yml");
        } else {
            new CivilizationApplication().run(args);
        }
    }

    @Override
    public void initialize(Bootstrap<CivilizationConfiguration> bootstrap) {
        bootstrap.addBundle(new Java8Bundle());
        bootstrap.addBundle(new AssetsBundle());
    }

    @Override
    public void run(CivilizationConfiguration configuration, Environment environment) throws Exception {
        DB db;
        MongoClient mongo;

        if (!Strings.isNullOrEmpty(configuration.mongouri)) {
            MongoClientURI clientURI = new MongoClientURI(configuration.mongouri);

            mongo = new MongoClient(clientURI);
            db = mongo.getDB(Objects.requireNonNull(clientURI.getDatabase()));
        } else {
            mongo = new MongoClient(configuration.mongohost, configuration.mongoport);
            db = mongo.getDB(configuration.mongodb);
        }
        MongoManaged mongoManaged = new MongoManaged(mongo);
        environment.lifecycle().manage(mongoManaged);

// Path: src/main/java/no/asgari/civilization/server/model/Chat.java
// @Data
// @JsonRootName("chat")
// @NoArgsConstructor
// @JsonIgnoreProperties(ignoreUnknown = true)
// public class Chat {
//     public static final String COL_NAME = "chat";
//     public static final String PBFID = "pbfId";
// 
//     @Id
//     @ObjectId
//     private String id;
// 
//     private String pbfId;
// 
//     @NotNull
//     private String username;
// 
//     @NotEmpty
//     private String message;
// 
//     @JsonSerialize(using = LocalDateTimeSerializer.class)
//     @JsonDeserialize(using = LocalDateTimeDeserializer.class)
//     private LocalDateTime created = LocalDateTime.now();
// 
//     @JsonIgnore
//     public long getCreatedInMillis() {
//         return created.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
//     }
// }
// 
// Path: src/main/java/no/asgari/civilization/server/model/Player.java
// @Data
// @JsonRootName("player")
// @NoArgsConstructor
// @JsonIgnoreProperties(ignoreUnknown = true)
// public class Player {
//     @JsonIgnore
//     public static final String COL_NAME = "player";
//     @JsonIgnore
//     public static final String USERNAME = "username";
//     @JsonIgnore
//     public static final String EMAIL = "email";
// 
//     @ObjectId
//     @Id
//     private String id;
// 
//     @NotBlank
//     //Unique
//     private String username;
// 
//     @Email
//     private String email;
// 
//     private boolean disableEmail = false;
// 
//     @NotBlank
//     private String password;
// 
//     private String newPassword;
// 
//     @JsonSerialize(using = LocalDateTimeSerializer.class)
//     @JsonDeserialize(using = LocalDateTimeDeserializer.class)
//     private LocalDateTime emailSent;
// 
//     /**
//      * Set of unique active games This may be reduntant as it can be calculated by looping through all pbfs.players and finding match.
//      */
//     private Set<String> gameIds = new HashSet<>();
// 
//     @JsonIgnore
//     public Optional<LocalDateTime> getIfEmailSent() {
//         return Optional.ofNullable(emailSent);
//     }
// }


// Path: src/main/java/no/asgari/civilization/server/application/CivilizationApplication.java
import com.codahale.metrics.MetricRegistry;
import com.google.common.base.Strings;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheBuilderSpec;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.mongodb.*;
import io.dropwizard.Application;
import io.dropwizard.assets.AssetsBundle;
import io.dropwizard.auth.basic.BasicCredentials;
import io.dropwizard.java8.Java8Bundle;
import io.dropwizard.java8.auth.AuthFactory;
import io.dropwizard.java8.auth.CachingAuthenticator;
import io.dropwizard.java8.auth.basic.BasicAuthFactory;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import lombok.extern.log4j.Log4j;
import no.asgari.civilization.server.model.Chat;
import no.asgari.civilization.server.model.Player;
import no.asgari.civilization.server.resource.*;
import org.eclipse.jetty.servlets.CrossOriginFilter;
import org.glassfish.hk2.utilities.Binder;
import org.mongojack.JacksonDBCollection;
import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import static org.eclipse.jetty.servlets.CrossOriginFilter.*;

/*
 * Copyright (c) 2015 Shervin Asgari
 * 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.
 */

package no.asgari.civilization.server.application;




@Log4j
@SuppressWarnings("unchecked")
public class CivilizationApplication extends Application<CivilizationConfiguration> {

    public static void main(String[] args) throws Exception {
        if (args == null || args.length == 0) {
            new CivilizationApplication().run("server", "src/main/resources/config.yml");
        } else {
            new CivilizationApplication().run(args);
        }
    }

    @Override
    public void initialize(Bootstrap<CivilizationConfiguration> bootstrap) {
        bootstrap.addBundle(new Java8Bundle());
        bootstrap.addBundle(new AssetsBundle());
    }

    @Override
    public void run(CivilizationConfiguration configuration, Environment environment) throws Exception {
        DB db;
        MongoClient mongo;

        if (!Strings.isNullOrEmpty(configuration.mongouri)) {
            MongoClientURI clientURI = new MongoClientURI(configuration.mongouri);

            mongo = new MongoClient(clientURI);
            db = mongo.getDB(Objects.requireNonNull(clientURI.getDatabase()));
        } else {
            mongo = new MongoClient(configuration.mongohost, configuration.mongoport);
            db = mongo.getDB(configuration.mongodb);
        }
        MongoManaged mongoManaged = new MongoManaged(mongo);
        environment.lifecycle().manage(mongoManaged);

        JacksonDBCollection<Player, String> playerCollection = JacksonDBCollection.wrap(db.getCollection(Player.COL_NAME), Player.class, String.class);