package oasis.tools;

import java.util.List;

import javax.inject.Inject;
import javax.inject.Provider;

import org.jongo.Jongo;
import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Iterables;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.typesafe.config.Config;

import oasis.jongo.JongoService;
import oasis.jongo.guice.JongoModule;
import oasis.model.authn.ClientType;
import oasis.openidconnect.OpenIdConnectModule;
import oasis.services.authn.CredentialsService;

public class GenerateClientPasswords extends CommandLineTool {

  public static void main(String[] args) throws Throwable {
    new GenerateClientPasswords().run(args);
  }

  @Option(name = "-n", aliases = "--dry-run")
  private boolean dryRun;

  @Inject JongoService jongoService;
  @Inject Provider<Jongo> jongoProvider;
  @Inject Provider<CredentialsService> credentialsServiceProvider;

  @Override
  protected Logger logger() {
    return LoggerFactory.getLogger(GenerateClientPasswords.class);
  }

  public void run(String[] args) throws Throwable {
    final Config config = init(args);

    if (dryRun) {
      logger().warn("Running in dry-run mode; changes will only be logged, the database won't be modified.");
    }

    final Injector injector = Guice.createInjector(
        JongoModule.create(config.getConfig("oasis.mongo")),
        // TODO: refactor to use a single subtree of the config
        OpenIdConnectModule.create(config.withOnlyPath("oasis.openid-connect")
            .withFallback(config.withOnlyPath("oasis.oauth"))
            .withFallback(config.withOnlyPath("oasis.session"))
            .withFallback(config.withOnlyPath("oasis.conf-dir")))
    );

    injector.injectMembers(this);

    jongoService.start();
    try {
      // Create credentials for each data providers and service providers in credentials collection
      List<String> dataProviderIds = jongoProvider.get().getCollection("applications").distinct("dataProviders.id").as(String.class);
      List<String> serviceProviderIds = jongoProvider.get().getCollection("applications").distinct("serviceProvider.id").as(String.class);

      for (String providerId : Iterables.concat(dataProviderIds, serviceProviderIds)) {
        if (providerId.equals("test")) {
          createCredentials("test", "password");
        } else {
          createCredentials(providerId, providerId);
        }
      }
    } finally {
      jongoService.stop();
    }
  }

  private void createCredentials(String providerId, String password) {
    logger().info("Initializing password for provider {} (password={})", providerId, password);
    if (!dryRun) {
      credentialsServiceProvider.get().setPassword(ClientType.PROVIDER, providerId, password);
    }
  }
}

@@ -1867,44 +1867,28 @@
 ach 
-data providers and service providers
+application instance
  in 
@@ -1933,157 +1933,19 @@
 ng%3E 
-dataProviderIds = jongoProvider.get().getCollection(%22applications%22).distinct(%22dataProviders.id%22).as(String.class);%0A      List%3CString%3E serviceProvider
+appInstance
 Ids 
@@ -1984,24 +1984,25 @@
 ion(%22app
-lication
+_instance
 s%22).dist
@@ -2011,24 +2011,8 @@
 ct(%22
-serviceProvider.
 id%22)
@@ -2066,61 +2066,22 @@
 d : 
-Iterables.concat(dataProviderIds, serviceProviderIds)
+appInstanceIds
 ) %7B%0A

Update GenerateClientPasswords for the new application data model.