package io.georocket.commands;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.delete;
import static com.github.tomakehurst.wiremock.client.WireMock.deleteRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;

import org.junit.Test;
import org.junit.runner.RunWith;

import com.github.tomakehurst.wiremock.client.VerificationException;

import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;

/**
 * Test for {@link DeleteCommand}
 * @author Michel Kraemer
 */
@RunWith(VertxUnitRunner.class)
public class DeleteCommandTest extends CommandTestBase<DeleteCommand> {
  @Override
  protected DeleteCommand createCommand() {
    return new DeleteCommand();
  }
  
  /**
   * Test no layer
   * @param context the test context
   * @throws Exception if something goes wrong
   */
  @Test
  public void noLayer(TestContext context) throws Exception {
    context.assertEquals(1, cmd.run(new String[] { }, in, out));
  }
  
  /**
   * Test empty layer
   * @param context the test context
   * @throws Exception if something goes wrong
   */
  @Test
  public void emptyLayer(TestContext context) throws Exception {
    context.assertEquals(1, cmd.run(new String[] { "" }, in, out));
  }
  
  /**
   * Verify that a certain DELETE request has been made
   * @param url the request URL
   * @param context the current test context
   */
  protected void verifyDeleted(String url, TestContext context) {
    try {
      verify(deleteRequestedFor(urlEqualTo(url)));
    } catch (VerificationException e) {
      context.fail(e);
    }
  }
  
  /**
   * Test a delete with a simple query
   * @param context the test context
   * @throws Exception if something goes wrong
   */
  @Test
  public void simpleQueryDelete(TestContext context) throws Exception {
    String url = "/store/?search=test";
    stubFor(delete(urlEqualTo(url))
        .willReturn(aResponse()
            .withStatus(204)));
    
    Async async = context.async();
    cmd.setEndHandler(exitCode -> {
      context.assertEquals(0, exitCode);
      verifyDeleted(url, context);
      async.complete();
    });
    
    cmd.run(new String[] { "test" }, in, out);
  }

  /**
   * Test a delete with query that consists of two terms
   * @param context the test context
   * @throws Exception if something goes wrong
   */
  @Test
  public void twoTermsQueryDelete(TestContext context) throws Exception {
    String url = "/store/?search=test1+test2";
    stubFor(delete(urlEqualTo(url))
        .willReturn(aResponse()
            .withStatus(204)));
    
    Async async = context.async();
    cmd.setEndHandler(exitCode -> {
      context.assertEquals(0, exitCode);
      verifyDeleted(url, context);
      async.complete();
    });
    
    cmd.run(new String[] { "test1", "test2" }, in, out);
  }
  
  /**
   * Test a delete with a layer but no query
   * @param context the test context
   * @throws Exception if something goes wrong
   */
  @Test
  public void layerNoQuery(TestContext context) throws Exception {
    String url = "/store/hello/world/";
    stubFor(delete(urlEqualTo(url))
        .willReturn(aResponse()
            .withStatus(204)));
    
    Async async = context.async();
    cmd.setEndHandler(exitCode -> {
      context.assertEquals(0, exitCode);
      verifyDeleted(url, context);
      async.complete();
    });
    
    cmd.run(new String[] { "-l", "hello/world" }, in, out);
  }
  
  /**
   * Test a delete with a layer and a query
   * @param context the test context
   * @throws Exception if something goes wrong
   */
  @Test
  public void layerQuery(TestContext context) throws Exception {
    String url = "/store/hello/world/?search=test";
    stubFor(delete(urlEqualTo(url))
        .willReturn(aResponse()
            .withStatus(204)));
    
    Async async = context.async();
    cmd.setEndHandler(exitCode -> {
      context.assertEquals(0, exitCode);
      verifyDeleted(url, context);
      async.complete();
    });
    
    cmd.run(new String[] { "-l", "hello/world", "test" }, in, out);
  }
}

@@ -3079,32 +3079,609 @@
 );%0A  %7D%0A  %0A  /**%0A
+   * Test to delete the root layer%0A   * @param context the test context%0A   * @throws Exception if something goes wrong%0A   */%0A  @Test%0A  public void rootLayer(TestContext context) throws Exception %7B%0A    String url = %22/store/%22;%0A    stubFor(delete(urlEqualTo(url))%0A        .willReturn(aResponse()%0A            .withStatus(204)));%0A    %0A    Async async = context.async();%0A    cmd.setEndHandler(exitCode -%3E %7B%0A      context.assertEquals(0, exitCode);%0A      verifyDeleted(url, context);%0A      async.complete();%0A    %7D);%0A    %0A    cmd.run(new String%5B%5D %7B %22-l%22, %22/%22 %7D, in, out);%0A  %7D%0A  %0A  /**%0A
    * Test a dele

Add test that checks if the whole database can be deleted