/*
 * JORAM: Java(TM) Open Reliable Asynchronous Messaging
 * Copyright (C) 2018 - 2019 ScalAgent Distributed Technologies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA.
 *
 * Initial developer(s): ScalAgent Distributed Technologies
 * Contributor(s): 
 */
package rest;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.core.Form;
import jakarta.ws.rs.client.Invocation.Builder;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.Link;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.UriBuilder;

import org.glassfish.jersey.client.ClientConfig;
import org.objectweb.util.monolog.api.BasicLevel;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class RestTest {
  static short jndi = 16400;
  static short jms = 16010;
  static short rest = 8989;

  public static void main(String[] args) throws Exception {
    org.objectweb.joram.client.jms.admin.AdminModule.connect("localhost", jms, "root", "root", 60);
    
    // create a Queue   
    org.objectweb.joram.client.jms.Queue queue =
        (org.objectweb.joram.client.jms.Queue) org.objectweb.joram.client.jms.Queue.create("queue"); 
    // create a user
    org.objectweb.joram.client.jms.admin.User user =
        org.objectweb.joram.client.jms.admin.User.create("joram", "marjo");
    // set permissions
    queue.setFreeReading();
    queue.setFreeWriting();

    javax.jms.ConnectionFactory cf =
        org.objectweb.joram.client.jms.tcp.TcpConnectionFactory.create("localhost", jms);

    Properties props = new Properties();
    props.setProperty("java.naming.factory.initial", "fr.dyade.aaa.jndi2.client.NamingContextFactory");
    props.setProperty("java.naming.factory.host", "localhost");
    props.setProperty("java.naming.factory.port", "16400");
    
    javax.naming.Context jndiCtx = new javax.naming.InitialContext(props);
    jndiCtx.rebind("cf", cf);
    jndiCtx.rebind("queue", queue);
    jndiCtx.close();

    org.objectweb.joram.client.jms.admin.AdminModule.disconnect();

    URI base = UriBuilder.fromUri("http://localhost:" + rest + "/joram/").build();
    Client client = ClientBuilder.newClient(new ClientConfig());
    WebTarget target = client.target(base);

    Builder builder = target.path("jndi").path("queue").request();
    Response response = builder.accept(MediaType.TEXT_PLAIN).head();
//    assertEquals("jndi-queue", 201, response.getStatus());
    System.out.println("jndi-queue: " + (response.getStatus() == 201));

    URI uriCreateCons = new URI(response.getLink("create-consumer").getUri().toString() + "-fp");
    URI uriCreateProd = new URI(response.getLink("create-producer").getUri().toString() + "-fp");
    
    Form auth = new Form().param("user", "joram").param("password", "marjo");

    // Creates a producer
    response = client.target(uriCreateProd)
        .request()
        .accept(MediaType.TEXT_PLAIN)
        .post(Entity.entity(auth, MediaType.APPLICATION_FORM_URLENCODED));
    
//    assertEquals("create-producer", 201, response.getStatus());
    System.out.println("create-producer: " + (response.getStatus() == 201));

    URI uriCloseProd = response.getLink("close-context").getUri();

    String message = "my test message";
    String messageNext = "my test message next";
    
    // Send a message
    response = client.target(response.getLink("send-message").getUri())
        .request()
        .accept(MediaType.TEXT_PLAIN)
        .post(Entity.entity(message, MediaType.TEXT_PLAIN));
//    assertEquals("send-message", 200, response.getStatus());
    System.out.println("send-message: " + (response.getStatus() == 200));
    
    // Send ane a message
    response = client.target(response.getLink("send-next-message").getUri())
        .request()
        .accept(MediaType.TEXT_PLAIN)
        .post(Entity.entity(messageNext, MediaType.TEXT_PLAIN));
//    assertEquals("send-next-message", 200, response.getStatus());
    System.out.println("sen-next-message: " + (response.getStatus() == 200));

    // Creates a consumer
    response = client.target(uriCreateCons)
        .request()
        .accept(MediaType.TEXT_PLAIN)
        .post(Entity.entity(auth, MediaType.APPLICATION_FORM_URLENCODED));
//    assertEquals("create-consumer", 201, response.getStatus());
    System.out.println("create-consumer: " + (response.getStatus() == 201));

    URI uriCloseCons = response.getLink("close-context").getUri();
    URI uriReceive = response.getLink("receive-message").getUri();
    
    builder = client.target(uriReceive)
        .request()
        .accept(MediaType.TEXT_PLAIN);
    response = builder.get();
    String msg = response.readEntity(String.class);
//    assertEquals(200, response.getStatus());
//    assertNotNull("receive-message", msg);
//    assertEquals("receive-message", message, msg);
    System.out.println("receive-message: " + (response.getStatus() == 200));

    uriReceive = response.getLink("receive-next-message").getUri();
    builder = client.target(uriReceive)
        .request()
        .accept(MediaType.TEXT_PLAIN);
    response = builder.get();
    msg = response.readEntity(String.class);
//    assertEquals(200, response.getStatus());
//    assertNotNull("receive-next-message", msg);
//    assertEquals("receive-next-message", messageNext, msg);
    System.out.println("receive-next-message: " + (response.getStatus() == 200));

    response = client.target(uriCloseProd)
        .request()
        .accept(MediaType.TEXT_PLAIN)
        .delete();
//    assertEquals("close-producer", 200, response.getStatus());
    System.out.println("close-producer: " + (response.getStatus() == 200));

    response = client.target(uriCloseCons)
        .request()
        .accept(MediaType.TEXT_PLAIN)
        .delete();
//    assertEquals("close-consumer", 200, response.getStatus());
    System.out.println("close-consumer: " + (response.getStatus() == 200));
  }
}
