package com.airlock.iam.login.application.configuration.geolocation;

import com.airlock.iam.common.application.configuration.geolocation.GeolocationProviderConfig;
import com.airlock.iam.common.domain.model.geolocation.GeolocationProvider;
import com.airlock.iam.login.infrastructure.geolocation.MaxMindGeolocationProvider;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.lifecycle.AfterConfigActivation;
import com.airlock.iam.plugin.api.annotation.lifecycle.BeforeConfigActivation;
import com.airlock.iam.plugin.api.annotation.lifecycle.BeforePluginDeactivation;
import com.airlock.iam.plugin.api.annotation.property.FileProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.File;

@Plugin(
   displayName = "MaxMind Geolocation Provider",
   description = "Geolocation provider based on a local <a href=\"http://dev.maxmind.com/geoip/geoip2/geolite2/\">MaxMind GeoLite2</a> City or Country database."
)
public class MaxMindGeolocationProviderConfig implements GeolocationProviderConfig {
   @FileProperty(
      description = "The Location of the GeoLite2 City or Country database (*.mmdb). GeoIP Legacy databases are not supported.<p/>Updates to this file are detected automatically.",
      assureExistence = true,
      assureReadable = true,
      isFile = true,
      optional = false,
      exampleValues = {"/opt/GeoLite2/GeoLite2-City.mmdb", "/opt/GeoLite2/GeoLite2-Country.mmdb", "instances/auth/GeoLite2-Country.mmdb"}
   )
   private File dbFileLocation;
   private MaxMindGeolocationProvider provider;

   public MaxMindGeolocationProviderConfig(File dbFileLocation) {
      this.dbFileLocation = dbFileLocation;
   }

   @AfterConfigActivation
   void preprocessConfiguration() {
      this.provider = new MaxMindGeolocationProvider(this.dbFileLocation);
   }

   @BeforePluginDeactivation
   @BeforeConfigActivation
   void cleanup() {
      if (this.provider != null) {
         this.provider.close();
      }
   }

   @Override
   public GeolocationProvider getProvider() {
      return this.provider;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static MaxMindGeolocationProviderConfig.MaxMindGeolocationProviderConfigBuilder builder() {
      return new MaxMindGeolocationProviderConfig.MaxMindGeolocationProviderConfigBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public MaxMindGeolocationProviderConfig() {
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class MaxMindGeolocationProviderConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private File dbFileLocation;

      @SuppressFBWarnings(justification = "generated code")
      MaxMindGeolocationProviderConfigBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public MaxMindGeolocationProviderConfig.MaxMindGeolocationProviderConfigBuilder dbFileLocation(File dbFileLocation) {
         this.dbFileLocation = dbFileLocation;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public MaxMindGeolocationProviderConfig build() {
         return new MaxMindGeolocationProviderConfig(this.dbFileLocation);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "MaxMindGeolocationProviderConfig.MaxMindGeolocationProviderConfigBuilder(dbFileLocation=" + this.dbFileLocation + ")";
      }
   }
}
