// Path: src/main/java/com/github/daniel_sc/rocketchat/modern_client/response/livechat/InitialData.java
// public class InitialData {
//  public Boolean enabled; //  true
//  public String title; //  'Rocket.Chat'
//  public String color; //  '#C1272D'
//  public Boolean registrationForm; //  true
//  public User visitor; //  undefined
//  public List<Trigger> triggers; //  []
//  public List<Department> departments; //  []
//  public Boolean allowSwitchingDepartments; //  true
//  public Boolean online; //  true
//  public String offlineColor; //  '#666666'
//  public String offlineMessage; //  'We are not online right now. Please leave us a message:'
//  public String offlineSuccessMessage; //  ''
//  public String offlineUnavailableMessage; //  ''
//  public Boolean displayOfflineForm; //  true
//  public Boolean videoCall; //  false
//  public String offlineTitle; //  'Leave a message'
//  public String language; //  'en'
//  public Boolean transcript; //  false
//  public String transcriptMessage; //  'Would you like a copy of this chat emailed?'
//  public String conversationFinishedMessage; //  'Conversation finished'
//  public Boolean nameFieldRegistrationForm; //  true
//  public Boolean emailFieldRegistrationForm; //  true
// 
//  @Override
//  public String toString() {
//   return "InitialData{" +
//           "enabled=" + enabled +
//           ", title='" + title + '\'' +
//           ", color='" + color + '\'' +
//           ", registrationForm=" + registrationForm +
//           ", visitor=" + visitor +
//           ", triggers=" + triggers +
//           ", departments=" + departments +
//           ", allowSwitchingDepartments=" + allowSwitchingDepartments +
//           ", online=" + online +
//           ", offlineColor='" + offlineColor + '\'' +
//           ", offlineMessage='" + offlineMessage + '\'' +
//           ", offlineSuccessMessage='" + offlineSuccessMessage + '\'' +
//           ", offlineUnavailableMessage='" + offlineUnavailableMessage + '\'' +
//           ", displayOfflineForm=" + displayOfflineForm +
//           ", videoCall=" + videoCall +
//           ", offlineTitle='" + offlineTitle + '\'' +
//           ", language='" + language + '\'' +
//           ", transcript=" + transcript +
//           ", transcriptMessage='" + transcriptMessage + '\'' +
//           ", conversationFinishedMessage='" + conversationFinishedMessage + '\'' +
//           ", nameFieldRegistrationForm=" + nameFieldRegistrationForm +
//           ", emailFieldRegistrationForm=" + emailFieldRegistrationForm +
//           '}';
//  }
// }
// 
// Path: src/main/java/com/github/daniel_sc/rocketchat/modern_client/response/livechat/LiveChatMessage.java
// public class LiveChatMessage {
//     public String msg;
//     public User u;
//     public String rid;
//     public String _id;
//     public String token;
//     public String alias;
//     public DateWrapper _updatedAt;
//     public DateWrapper ts;
//     public Boolean newRoom;
//     public Boolean showConnecting;
// 
//     @Override
//     public String toString() {
//         return "LiveChatMessage{" +
//                 "msg='" + msg + '\'' +
//                 ", u=" + u +
//                 ", rid='" + rid + '\'' +
//                 ", _id='" + _id + '\'' +
//                 ", token='" + token + '\'' +
//                 ", alias='" + alias + '\'' +
//                 ", _updatedAt=" + _updatedAt +
//                 ", ts=" + ts +
//                 ", newRoom=" + newRoom +
//                 ", showConnecting=" + showConnecting +
//                 '}';
//     }
// }
// 
// Path: src/main/java/com/github/daniel_sc/rocketchat/modern_client/response/livechat/RegisterGuest.java
// public class RegisterGuest {
//     public String userId;
//     public Visitor visitor;
// 
//     @Override
//     public String toString() {
//         return "RegisterGuest{" +
//                 "userId='" + userId + '\'' +
//                 ", visitor=" + visitor +
//                 '}';
//     }
// }


import com.github.daniel_sc.rocketchat.modern_client.request.*;
import com.github.daniel_sc.rocketchat.modern_client.response.*;
import com.github.daniel_sc.rocketchat.modern_client.response.livechat.InitialData;
import com.github.daniel_sc.rocketchat.modern_client.response.livechat.LiveChatMessage;
import com.github.daniel_sc.rocketchat.modern_client.response.livechat.RegisterGuest;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.Subject;
import javax.websocket.*;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
        return send(request, failOnError(r -> {
            if (r.result == null) {
                throw new IllegalStateException("Message result is empty!");
            }
            return GSON.fromJson(r.result, ChatMessage.class);
        }));
    }

    public CompletableFuture<ChatMessage> updateMessage(String msg, String _id) {
        return updateMessageWithAttachments(msg, _id, null, null);
    }

    public CompletableFuture<ChatMessage> updateMessageWithAttachments(String msg, String _id, Boolean groupable, List<Attachment> attachments) {
        MethodRequest request = new MethodRequest("updateMessage", SendMessageParam.forUpdate(_id, msg, null, null, null, null, groupable, attachments));
        return send(request, failOnError(r -> GSON.fromJson(GSON.toJsonTree(r.result), ChatMessage.class)));
    }

    public CompletableFuture<List<Permission>> getPermissions() {
        return send(new MethodRequest("permissions/get"),
                failOnError(r -> GSON.fromJson(GSON.toJsonTree(r.result), new TypeToken<List<Permission>>() {
                }.getType())));
    }

    public CompletableFuture<InitialData> livechatGetInitialData(String visitorToken) {
        MethodRequest request;
        if (visitorToken != null) {
            request = new MethodRequest("livechat:getInitialData", visitorToken);
        } else {
            request = new MethodRequest("livechat:getInitialData");
        }
// Path: src/main/java/com/github/daniel_sc/rocketchat/modern_client/response/livechat/InitialData.java
// public class InitialData {
//  public Boolean enabled; //  true
//  public String title; //  'Rocket.Chat'
//  public String color; //  '#C1272D'
//  public Boolean registrationForm; //  true
//  public User visitor; //  undefined
//  public List<Trigger> triggers; //  []
//  public List<Department> departments; //  []
//  public Boolean allowSwitchingDepartments; //  true
//  public Boolean online; //  true
//  public String offlineColor; //  '#666666'
//  public String offlineMessage; //  'We are not online right now. Please leave us a message:'
//  public String offlineSuccessMessage; //  ''
//  public String offlineUnavailableMessage; //  ''
//  public Boolean displayOfflineForm; //  true
//  public Boolean videoCall; //  false
//  public String offlineTitle; //  'Leave a message'
//  public String language; //  'en'
//  public Boolean transcript; //  false
//  public String transcriptMessage; //  'Would you like a copy of this chat emailed?'
//  public String conversationFinishedMessage; //  'Conversation finished'
//  public Boolean nameFieldRegistrationForm; //  true
//  public Boolean emailFieldRegistrationForm; //  true
// 
//  @Override
//  public String toString() {
//   return "InitialData{" +
//           "enabled=" + enabled +
//           ", title='" + title + '\'' +
//           ", color='" + color + '\'' +
//           ", registrationForm=" + registrationForm +
//           ", visitor=" + visitor +
//           ", triggers=" + triggers +
//           ", departments=" + departments +
//           ", allowSwitchingDepartments=" + allowSwitchingDepartments +
//           ", online=" + online +
//           ", offlineColor='" + offlineColor + '\'' +
//           ", offlineMessage='" + offlineMessage + '\'' +
//           ", offlineSuccessMessage='" + offlineSuccessMessage + '\'' +
//           ", offlineUnavailableMessage='" + offlineUnavailableMessage + '\'' +
//           ", displayOfflineForm=" + displayOfflineForm +
//           ", videoCall=" + videoCall +
//           ", offlineTitle='" + offlineTitle + '\'' +
//           ", language='" + language + '\'' +
//           ", transcript=" + transcript +
//           ", transcriptMessage='" + transcriptMessage + '\'' +
//           ", conversationFinishedMessage='" + conversationFinishedMessage + '\'' +
//           ", nameFieldRegistrationForm=" + nameFieldRegistrationForm +
//           ", emailFieldRegistrationForm=" + emailFieldRegistrationForm +
//           '}';
//  }
// }
// 
// Path: src/main/java/com/github/daniel_sc/rocketchat/modern_client/response/livechat/LiveChatMessage.java
// public class LiveChatMessage {
//     public String msg;
//     public User u;
//     public String rid;
//     public String _id;
//     public String token;
//     public String alias;
//     public DateWrapper _updatedAt;
//     public DateWrapper ts;
//     public Boolean newRoom;
//     public Boolean showConnecting;
// 
//     @Override
//     public String toString() {
//         return "LiveChatMessage{" +
//                 "msg='" + msg + '\'' +
//                 ", u=" + u +
//                 ", rid='" + rid + '\'' +
//                 ", _id='" + _id + '\'' +
//                 ", token='" + token + '\'' +
//                 ", alias='" + alias + '\'' +
//                 ", _updatedAt=" + _updatedAt +
//                 ", ts=" + ts +
//                 ", newRoom=" + newRoom +
//                 ", showConnecting=" + showConnecting +
//                 '}';
//     }
// }
// 
// Path: src/main/java/com/github/daniel_sc/rocketchat/modern_client/response/livechat/RegisterGuest.java
// public class RegisterGuest {
//     public String userId;
//     public Visitor visitor;
// 
//     @Override
//     public String toString() {
//         return "RegisterGuest{" +
//                 "userId='" + userId + '\'' +
//                 ", visitor=" + visitor +
//                 '}';
//     }
// }


// Path: src/main/java/com/github/daniel_sc/rocketchat/modern_client/RocketChatClient.java
import com.github.daniel_sc.rocketchat.modern_client.request.*;
import com.github.daniel_sc.rocketchat.modern_client.response.*;
import com.github.daniel_sc.rocketchat.modern_client.response.livechat.InitialData;
import com.github.daniel_sc.rocketchat.modern_client.response.livechat.LiveChatMessage;
import com.github.daniel_sc.rocketchat.modern_client.response.livechat.RegisterGuest;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.Subject;
import javax.websocket.*;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;

        return send(request, failOnError(r -> {
            if (r.result == null) {
                throw new IllegalStateException("Message result is empty!");
            }
            return GSON.fromJson(r.result, ChatMessage.class);
        }));
    }

    public CompletableFuture<ChatMessage> updateMessage(String msg, String _id) {
        return updateMessageWithAttachments(msg, _id, null, null);
    }

    public CompletableFuture<ChatMessage> updateMessageWithAttachments(String msg, String _id, Boolean groupable, List<Attachment> attachments) {
        MethodRequest request = new MethodRequest("updateMessage", SendMessageParam.forUpdate(_id, msg, null, null, null, null, groupable, attachments));
        return send(request, failOnError(r -> GSON.fromJson(GSON.toJsonTree(r.result), ChatMessage.class)));
    }

    public CompletableFuture<List<Permission>> getPermissions() {
        return send(new MethodRequest("permissions/get"),
                failOnError(r -> GSON.fromJson(GSON.toJsonTree(r.result), new TypeToken<List<Permission>>() {
                }.getType())));
    }

    public CompletableFuture<InitialData> livechatGetInitialData(String visitorToken) {
        MethodRequest request;
        if (visitorToken != null) {
            request = new MethodRequest("livechat:getInitialData", visitorToken);
        } else {
            request = new MethodRequest("livechat:getInitialData");
        }
        return send(request, failOnError(r -> GSON.fromJson(GSON.toJsonTree(r.result), InitialData.class)));