package org.jboss.resteasy.test.spring.inmodule;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.logging.Logger;
import org.jboss.resteasy.client.ClientURI;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.test.spring.inmodule.resource.Contact;
import org.jboss.resteasy.test.spring.inmodule.resource.ContactService;
import org.jboss.resteasy.test.spring.inmodule.resource.Contacts;
import org.jboss.resteasy.test.spring.inmodule.resource.ContactsResource;
import org.jboss.resteasy.util.HttpHeaderNames;
import org.jboss.resteasy.utils.PortProviderUtil;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

/**
 * @tpSubChapter Spring
 * @tpChapter Integration tests
 * @tpSince RESTEasy 3.0.16
 */
@RunWith(Arquillian.class)
@RunAsClient
public class ContactsTest {

    private static Logger logger = Logger.getLogger(ContactsTest.class);
    private static ContactProxy proxy;
    private static ResteasyClient client;

    @Path(ContactsResource.CONTACTS_URL)
    public interface ContactProxy {
        @Path("data")
        @POST
        @Consumes(MediaType.APPLICATION_XML)
        Response createContact(Contact contact);

        @GET
        @Produces(MediaType.APPLICATION_XML)
        Contact getContact(@ClientURI String uri);

        @GET
        String getString(@ClientURI String uri);
    }

    @Deployment
    private static Archive<?> deploy() {
        WebArchive archive = ShrinkWrap.create(WebArchive.class, ContactsTest.class.getSimpleName() + ".war")
                .addClass(ContactsResource.class)
                .addClass(ContactService.class)
                .addClass(Contacts.class)
                .addClass(Contact.class)
                .addClass(ContactsTest.class)
                .addAsWebInfResource(ContactsTest.class.getPackage(), "contacts/web.xml", "web.xml")
                .addAsWebInfResource(ContactsTest.class.getPackage(), "contacts/springmvc-servlet.xml", "springmvc-servlet.xml");
        archive.addAsManifestResource(new StringAsset("Dependencies: org.springframework.spring meta-inf\n"), "MANIFEST.MF");
        return archive;
    }

    private String generateURL(String path) {
        return PortProviderUtil.generateURL(path, ContactsTest.class.getSimpleName());
    }

    /**
     * @tpTestDetails Test is using component-scan and annotation-config spring features. This features are unusable if
     * running with spring dependency 3.2.8.RELEASE and earlier. Only 3.2.9.RELEASE and spring 4 are supported.
     * @tpSince RESTEasy 3.0.16
     */
    @Test
    public void testData() {
        client = new ResteasyClientBuilder().build();
        proxy = client.target(generateURL("")).proxy(ContactProxy.class);
        Response response = proxy.createContact(new Contact("Solomon", "Duskis"));
        Assert.assertEquals(201, response.getStatus());
        String duskisUri = (String) response.getMetadata().getFirst(HttpHeaderNames.LOCATION);
        logger.info(duskisUri);
        Assert.assertTrue("Unexpected response from the server", duskisUri.endsWith(ContactsResource.CONTACTS_URL + "/data/Duskis"));
        response.close();
        Assert.assertEquals("Unexpected response from the server", "Solomon", proxy.getContact(duskisUri).getFirstName());
        response = proxy.createContact(new Contact("Bill", "Burkie"));
        response.close();
        logger.info(proxy.getString(generateURL(ContactsResource.CONTACTS_URL + "/data")));
    }
}
