package com.onsemi.middleware.UECommon.model;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.persistence.Id;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.onsemi.middleware.UECommon.cache.event.annotation.ClusterEventNotify;
import com.onsemi.middleware.UECommon.event.cluster.ConnectionJndiChangeEvent;
import com.onsemi.middleware.connector.AdvancedProperty;

import io.swagger.v3.oas.annotations.media.Schema;

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
@Schema(anyOf = {ConnectionBeanDb.class,
                 ConnectionJndiBeanFtp.class,
ConnectionJndiBeanPgp.class,
ConnectionJndiCascadeBean.class,
ConnectionJndiCascadeExpImpBean.class,
ConnectionJndiCdBean.class,
ConnectionJndiCxfBean.class,
ConnectionJndiEmailBean.class,
ConnectionJndiExchangeBean.class,
ConnectionJndiHttpBean.class,
ConnectionJndiJmsBean.class,
ConnectionJndiWebServiceBean.class})
public class ConnectionJndiBean implements Serializable {

    @Id
    @ClusterEventNotify({ConnectionJndiChangeEvent.class})
    private int id;
    @ClusterEventNotify({ConnectionJndiChangeEvent.class})
    @Schema(description = "Connection jndi name, which can be found in the interface connections tab.")
    private String name;
    @ClusterEventNotify({ConnectionJndiChangeEvent.class})
    private Integer connectionId;
    @ClusterEventNotify({ConnectionJndiChangeEvent.class})
    private int interfaceId;
    private String updatedBy;
    private Date updatedDate;
    @ClusterEventNotify({ConnectionJndiChangeEvent.class})
    @Deprecated
    @Schema(description = "Type of connection jndi", example = "D-database,F-ftp,W-webservice,,WE-cxf,J-jms,CA-cascade,H-http,CD-central dat,X-exchange. Deprecated field - use @class to indicate / identify the type.")
    private String type;
    @ClusterEventNotify({ConnectionJndiChangeEvent.class})
    private String advancedConnectionOptions;

    private String inOut;

    public ConnectionJndiBean(int id,
                              String name,
                              int connectionId,
                              int interfaceId,
                              String updatedBy,
                              Date updatedDate,
                              String inOut) {
        super();
        this.id = id;
        this.name = name;
        this.connectionId = connectionId;
        this.interfaceId = interfaceId;
        this.updatedBy = updatedBy;
        this.updatedDate = updatedDate;
        this.inOut = inOut;
    }

    public ConnectionJndiBean() {
    }
    
    public Optional<Class<? extends ConnectionBean>> getRelatedConnectionClass() {
    	return Optional.empty();
    }

    public int getId() {
        return id;
    }

    public Integer getConnectionId() {
        return connectionId;
    }

    public void setConnectionId(Integer connectionId) {
        this.connectionId = connectionId;
    }

    public String getUpdatedBy() {
        return updatedBy;
    }

    public void setUpdatedBy(String updatedBy) {
        this.updatedBy = updatedBy;
    }

    public Date getUpdatedDate() {
        return updatedDate;
    }

    public void setUpdatedDate(Date updatedDate) {
        this.updatedDate = updatedDate;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getInterfaceId() {
        return interfaceId;
    }

    public void setInterfaceId(int interfaceId) {
        this.interfaceId = interfaceId;
    }

    public String getInOut() {
        return inOut;
    }

    public void setInOut(String inOut) {
        this.inOut = inOut;
    }

    @Override
    public String toString() {
        return "ConnectionJndiBean [id=" + id + ", name=" + name + ", connectionId=" + connectionId + ", interfaceId=" + interfaceId + ", updatedBy=" + updatedBy + ", updatedDate=" + updatedDate + ", inOut=" + inOut + ", advancedConnectionOptions=" + advancedConnectionOptions + "]";
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getAdvancedConnectionOptions() {
        return advancedConnectionOptions;
    }

    public void setAdvancedConnectionOptions(String advancedConnectionOptions) {
        this.advancedConnectionOptions = advancedConnectionOptions;
    }

    public Optional<String> getAdvancedOption(AdvancedProperty optionName) {
        if (advancedConnectionOptions == null || advancedConnectionOptions.isEmpty()) {
            return Optional.empty();
        } else {
            String[] variousOpts = advancedConnectionOptions.split(";");
            Map<String, String> propertyMap = Arrays.stream(variousOpts)
                                                    .collect(Collectors.toMap(keyPair -> ((String) keyPair).split(":")[0].trim(),
                                                                              keyPair -> ((String) keyPair).split(":")[1].trim(),
                                                                              (val1, val2) -> val2));
            return Optional.ofNullable(propertyMap.get(optionName.getPropertyName()));
        }
    }
}
