package no.javabin.heroes.slack;

import no.javabin.heroes.Profile;
import no.javabin.infrastructure.ExceptionUtil;
import no.javabin.infrastructure.http.HttpUrl;
import org.jsonbuddy.JsonObject;
import org.jsonbuddy.parse.JsonParser;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class SlackProfile implements Profile {

    private boolean hasAdminScope;

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public String getEmail() {
        return email;
    }

    @Override
    public String getTwitterHandle() {
        return this.twitterHandle.orElse(null);
    }

    @Override
    public boolean isAdmin() {
        try {
            JsonObject conversations = slackJsonGet(accessToken, "conversations.list");
            // id: CEN9Z1E23
            admin = conversations.requiredArray("channels")
                    .objectStream()
                    .filter(channel -> channel.requiredBoolean("is_member"))
                    .map(channel -> channel.requiredString("name"))
                    .anyMatch(s -> s.equals("admin"));
            return admin;
        } catch (IOException e) {
            throw ExceptionUtil.softenException(e);
        }
    }

    @Override
    public boolean hasAdminScope() {
        return hasAdminScope;
    }

    @Override
    public List<JsonObject> listUsers() throws IOException {
        JsonObject userList = slackJsonGet(accessToken, "users.list");
        return userList
                .requiredArray("members")
                .objectStream()
                .filter(o -> !o.booleanValue("is_bot").orElse(false))
                .map(o -> o.requiredObject("profile"))
                .filter(o -> o.containsKey("email"))
                .map(o -> new JsonObject()
                        .put("name", o.requiredString("real_name"))
                        .put("avatarImage", o.stringValue("image_72").orElse(null))
                        .put("image_192", o.stringValue("image_192").orElse(null))
                        .put("email", o.requiredString("email"))
                )
                .collect(Collectors.toList());
    }

    private String username;

    private boolean admin;

    private String accessToken;

    private String email;

    private Optional<String> twitterHandle;

    SlackProfile(JsonObject tokenResponse) throws IOException {
        this.accessToken = tokenResponse.requiredString("access_token");

        List<String> scopes = Arrays.asList(tokenResponse.requiredString("scope").split(","));
        this.hasAdminScope = scopes.contains("users:read.email");

        JsonObject userProfile = slackJsonGet(accessToken, "users.profile.get");
        this.username = userProfile.requiredObject("profile").requiredString("real_name");
        this.email = userProfile.requiredObject("profile").requiredString("email");
        this.twitterHandle = userProfile.requiredObject("profile").stringValue("twitter");

        JsonObject conversations = slackJsonGet(accessToken, "conversations.list");
        // id: CEN9Z1E23
        admin = conversations.requiredArray("channels")
                .objectStream()
                .filter(channel -> channel.requiredBoolean("is_member"))
                .map(channel -> channel.requiredString("name"))
                .anyMatch(s -> s.equals("admin"));
    }

    public JsonObject slackJsonGet() throws IOException {
        return slackJsonGet(accessToken, "conversations.list");
    }

    public JsonObject slackJsonGet(String accessToken) throws IOException {
        return slackJsonGet(accessToken, "conversations.list");
    }

    private JsonObject slackJsonGet(String accessToken, String apiName) throws IOException {
        return JsonParser.parseToObject(
                new HttpUrl("https://slack.com/api/" + apiName)
                .addParameter("token", accessToken)
                .toURL()
        );
    }

}

@@ -113,55 +113,8 @@
 il;%0A
-import no.javabin.infrastructure.http.HttpUrl;%0A
 impo
@@ -210,16 +210,68 @@
 eption;%0A
+import java.net.URL;%0Aimport java.net.URLConnection;%0A
 import j
@@ -823,32 +823,33 @@
  = slackJsonGet(
+%22
 accessToken, %22co
@@ -835,32 +835,33 @@
 Get(%22accessToken
+%22
 , %22conversations
@@ -857,32 +857,69 @@
 nversations.list
+?types=private_channel,public_channel
 %22);%0A            
@@ -1044,38 +1044,40 @@
                .
-filter
+anyMatch
 (channel -%3E chan
@@ -1088,36 +1088,45 @@
 required
-Boolean(%22is_member%22)
+String(%22name%22).equals(%22admin%22
 )%0A      
@@ -1135,39 +1135,34 @@
             
-.map(channel -%3E
+        &&
  channel.req
@@ -1170,74 +1170,95 @@
 ired
-String(%22name%22))%0A                    .anyMatch(s -%3E s.equals(%22admin
+Boolean(%22is_member%22)%0A                            && channel.requiredBoolean(%22is_private
 %22));
@@ -3199,28 +3199,50 @@
 sations.list
+?types=private_channel
 %22);%0A
-
         // i
@@ -3534,37 +3534,38 @@
 ));%0A    %7D%0A%0A    p
-ublic
+rivate
  JsonObject slac
@@ -3577,532 +3577,287 @@
 Get(
-) throws IOException %7B%0A        return slackJsonGet(accessToken, %22conversations.list%22);%0A    %7D%0A%0A    public JsonObject slackJsonGet(String accessToken) throws IOException %7B%0A        return slackJsonGet(accessToken, %22conversations.list%22
+String accessToken, String path) throws IOException %7B%0A        URLConnection connection = new URL(%22https://slack.com/api/%22 + path).openConnection(
 );%0A    
-%7D%0A%0A
     
-private JsonObject slackJsonGet(String accessToken, String apiName) throws IOException %7B%0A        return JsonParser.parseToObject(%0A                new HttpUrl(%22https://slack.com/api/%22 + apiName)%0A                .addParameter(%22token%22, accessToken)%0A                .toURL()%0A        
+connection.setRequestProperty(%22Authorization%22, %22Bearer %22 + accessToken);%0A        return JsonParser.parseToObject(connection
 );%0A 

Find privileges based on private, not public channels