package ch.wisv.connect.common.model;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import org.mitre.openid.connect.model.DefaultUserInfo;
import org.mitre.openid.connect.model.UserInfo;

import java.lang.reflect.Type;
import java.util.Objects;
import java.util.Set;

/**
 * CH Connect UserInfo.
 */
public class CHUserInfo extends DefaultUserInfo {
    private String netid;
    private String studentNumber;
    private String ldapUsername;
    private Set<String> ldapGroups;

    private transient JsonObject src;

    private static Gson gson = new GsonBuilder().setPrettyPrinting().create();
    private final static Type stringSetType = new TypeToken<Set<String>>() {
    }.getType();


    public String getNetid() {
        return netid;
    }

    public void setNetid(String netid) {
        this.netid = netid;
    }

    public String getStudentNumber() {
        return studentNumber;
    }

    public void setStudentNumber(String studentNumber) {
        this.studentNumber = studentNumber;
    }

    public String getLdapUsername() {
        return ldapUsername;
    }

    public void setLdapUsername(String ldapUsername) {
        this.ldapUsername = ldapUsername;
    }

    public Set<String> getLdapGroups() {
        return ldapGroups;
    }

    public void setLdapGroups(Set<String> ldapGroups) {
        this.ldapGroups = ldapGroups;
    }

    @Override
    public JsonObject getSource() {
        return src;
    }

    @Override
    public void setSource(JsonObject src) {
        this.src = src;
    }

    @Override
    public JsonObject toJson() {
        if (src == null) {
            JsonObject obj = super.toJson();

            obj.addProperty("netid", this.getNetid());
            obj.addProperty("student_number", this.getStudentNumber());
            obj.addProperty("ldap_username", this.getLdapUsername());
            obj.addProperty("ldap_groups", gson.toJson(ldapGroups));

            return obj;
        } else {
            return src;
        }

    }

    public static UserInfo fromJson(JsonObject obj) {
        CHUserInfo ui = (CHUserInfo) DefaultUserInfo.fromJson(obj);

        ui.setSource(obj);

        ui.setNetid(nullSafeGetString(obj, "netid"));
        ui.setStudentNumber(nullSafeGetString(obj, "student_number"));
        ui.setLdapUsername(nullSafeGetString(obj, "ldap_username"));
        ui.setLdapGroups(gson.<Set<String>>fromJson(obj.getAsJsonArray("ldap_groups"), stringSetType));

        return ui;
    }

    private static String nullSafeGetString(JsonObject obj, String field) {
        return obj.has(field) && obj.get(field).isJsonPrimitive() ? obj.get(field).getAsString() : null;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof CHUserInfo)) return false;
        if (!super.equals(o)) return false;
        CHUserInfo that = (CHUserInfo) o;
        return Objects.equals(netid, that.netid) &&
                Objects.equals(studentNumber, that.studentNumber) &&
                Objects.equals(ldapUsername, that.ldapUsername) &&
                Objects.equals(ldapGroups, that.ldapGroups);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), netid, studentNumber, ldapUsername, ldapGroups);
    }
}

@@ -65,44 +65,8 @@
 on;%0A
-import com.google.gson.GsonBuilder;%0A
 impo
@@ -616,44 +616,8 @@
 Gson
-Builder().setPrettyPrinting().create
 ();%0A
@@ -1884,32 +1884,24 @@
      obj.add
-Property
 (%22ldap_group
@@ -1915,16 +1915,20 @@
 n.toJson
+Tree
 (ldapGro
@@ -2006,25 +2006,24 @@
 ;%0A        %7D%0A
-%0A
     %7D%0A%0A    p
@@ -2095,17 +2095,20 @@
 fo ui = 
-(
+new 
 CHUserIn
@@ -2113,66 +2113,872 @@
 Info
-) DefaultUserInfo.fromJson(obj);%0A%0A        ui.setSource(obj
+();%0A%0A        ui.setSource(obj);%0A%0A        UserInfo dui = DefaultUserInfo.fromJson(obj);%0A        ui.setSub(dui.getSub());%0A        ui.setName(dui.getName());%0A        ui.setPreferredUsername(dui.getPreferredUsername());%0A        ui.setGivenName(dui.getGivenName());%0A        ui.setFamilyName(dui.getFamilyName());%0A        ui.setMiddleName(dui.getMiddleName());%0A        ui.setNickname(dui.getNickname());%0A        ui.setProfile(dui.getProfile());%0A        ui.setPicture(dui.getPicture());%0A        ui.setWebsite(dui.getWebsite());%0A        ui.setGender(dui.getGender());%0A        ui.setZoneinfo(dui.getZoneinfo());%0A        ui.setLocale(dui.getLocale());%0A        ui.setUpdatedTime(dui.getUpdatedTime());%0A        ui.setBirthdate(dui.getBirthdate());%0A        ui.setEmail(dui.getEmail());%0A        ui.setEmailVerified(dui.getEmailVerified());%0A        ui.setAddress(dui.getAddress()
 );%0A%0A
@@ -3234,19 +3234,8 @@
 .get
-AsJsonArray
 (%22ld

Fix UserInfo JSON serialization