/*
 * Copyright 2017 The Mifos Initiative.
 *
 * 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 io.mifos.core.test.servicestarter;

import io.mifos.core.api.util.ApiFactory;
import io.mifos.core.test.env.TestEnvironment;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.junit.rules.ExternalResource;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.core.annotation.AnnotatedElementUtils;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import static io.mifos.core.test.env.TestEnvironment.SPRING_CLOUD_DISCOVERY_ENABLED_PROPERTY;

/**
 * @author Myrle Krantz
 */
@SuppressWarnings({"unused", "WeakerAccess"})
public class Microservice<T> extends ExternalResource {

  private final Class<T> clazz;
  private final String artifactName;
  private final String artifactVersion;
  final TestEnvironment processEnvironment;
  final IntegrationTestEnvironment integrationTestEnvironment;
  final String applicationName;
  private ApiFactory apiFactory;
  private Process process;
  private T api;

  public Microservice(
          final Class<T> clazz,
          final String artifactName,
          final String artifactVersion,
          final IntegrationTestEnvironment integrationTestEnvironment) {
    this.clazz = clazz;
    this.artifactName = artifactName;
    this.artifactVersion = artifactVersion;
    applicationName = AnnotatedElementUtils.getMergedAnnotationAttributes(clazz, FeignClient.class).getString("value");
    this.processEnvironment = new TestEnvironment(applicationName);
    processEnvironment.setProperty(TestEnvironment.SERVER_PORT_PROPERTY, integrationTestEnvironment.getFreshPort().toString());
    processEnvironment.setKeyPair(integrationTestEnvironment.getSeshatPublicKey(), integrationTestEnvironment.getSeshatPrivateKey());

    //https://github.com/spring-cloud/spring-cloud-netflix/issues/373
    //http://blog.abhijitsarkar.org/technical/netflix-eureka/
    processEnvironment.setProperty("eureka.client.serviceUrl.defaultZone", EurekaForTest.DEFAULT_ZONE);
    processEnvironment.setProperty(SPRING_CLOUD_DISCOVERY_ENABLED_PROPERTY, "true");
    processEnvironment.setProperty("eureka.instance.hostname", "localhost");
    processEnvironment.setProperty("eureka.client.fetchRegistry", "true");
    processEnvironment.setProperty("eureka.registration.enabled", "true");
    processEnvironment.setProperty("eureka.instance.leaseRenewalIntervalInSeconds", "1"); //Speed up registration for test purposes.
    processEnvironment.setProperty("eureka.client.initialInstanceInfoReplicationIntervalSeconds", "0");  //Speed up initial registration for test purposes.
    processEnvironment.setProperty("eureka.client.instanceInfoReplicationIntervalSeconds", "1");

    this.integrationTestEnvironment = integrationTestEnvironment;
  }

  @Override
  protected void before() throws InterruptedException, IOException, ArtifactResolutionException {
    start();
  }

  @Override
  protected void after() {
    try {
      kill();
    } catch (final InterruptedException e) {
      System.out.println("Interrupt raised, but microservice is already going down, so ignoring.");
    }
  }

  public void start() throws ArtifactResolutionException, IOException, InterruptedException {

    final ArtifactResolver artifactResolver = new ArtifactResolver(
            IntegrationTestEnvironment.getArtifactoryDirectory());

    final File jarFile = artifactResolver.getJarFile(artifactName, "io.mifos." + artifactName, "service-boot", artifactVersion);

    final ProcessBuilder processBuilder
            = new ProcessBuilder(IntegrationTestEnvironment.getJava(), "-jar", jarFile.getAbsolutePath());
    processEnvironment.populateProcessEnvironment(processBuilder);
    processBuilder.inheritIO();

    process = processBuilder.start();
    TimeUnit.SECONDS.sleep(40); //TODO: Replace this with event listening.
  }

  public int kill() throws InterruptedException {
    process.destroy();
    process.waitFor();
    return process.exitValue();
  }

  public void setApiFactory(final ApiFactory newValue)
  {
    this.apiFactory = newValue;
  }

  public T api() {
    if (this.api == null) {
      this.api = this.apiFactory.create(clazz, processEnvironment.serverURI());
    }
    return this.api;
  }

  public String uri() {
    return processEnvironment.serverURI();
  }

  public TestEnvironment getProcessEnvironment()
  {
    return processEnvironment;
  }

  public String name() {
    return applicationName;
  }
}
