package in.cdac.medinfo.csnotk.csnoserv.rest;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;
import static  in.cdac.medinfo.csnotk.csnoserv.CSnoServResource.*;
import in.cdac.medinfo.csnotk.csnoserv.CSnoServResource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import in.cdac.medinfo.csnotk.csnolib.commons.Constants;
import in.cdac.medinfo.csnotk.csnolib.commons.EnumDirection;
import in.cdac.medinfo.csnotk.csnolib.commons.EnumRelationshipType;
import in.cdac.medinfo.csnotk.csnolib.commons.EnumSemanticTag;
import in.cdac.medinfo.csnotk.csnolib.model.Concept;
import in.cdac.medinfo.csnotk.csnolib.model.Refset;
import in.cdac.medinfo.csnotk.csnolib.model.Relationship;


//Logs
import in.cdac.medinfo.csnotk.csnolib.util.LoggerUtility;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
//ECL
import java.util.HashSet;
import java.util.stream.Collectors;
import in.cdac.medinfo.csnotk.csnoserv.dto.ConceptTotalDTO;

@Path("/explore")
public class ExploreController{


    /**
     * Returns all descendants of concept
     *
     * @param id       {@link String} concept id for which lookup is to be done
     * @param callback {@link String} name of the callback function in a jsonp
     *                 request</br>
     *                 (for allowing cross domain request)
     */
    @GET
    @Produces({ MediaType.APPLICATION_JSON + ";charset=utf-8" })
    @Path("/alldescendants")
    public Response getAllConceptChilderns(@QueryParam("id") String id, @QueryParam("count") Boolean count,
                                           @QueryParam("callback") String callback) {

        CSnoServResource.initProperties();
        Logger logger = LogManager.getLogger(CSnoServResource.class);

        if (id == null || id.equalsIgnoreCase("") || !id.matches(_0_9)) {
            logger.error(LoggerUtility.Exception, INVALID_QUERY_PARAMETER_VALUE_ID , id);
            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());
        }

        String jsonString;
        if (count != null && count ) {
            try {
                jsonString = CSnoServResource.gson.toJson(CSnoServResource.agent.getIsARelationshipsWithCount(id.trim()));
            } catch (Exception e) // caches any of the service exceptions
            {
                // Log the Exception
                logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
                return CORSHeaderSupport.addCORSHeader(Response.Status.INTERNAL_SERVER_ERROR,Response.Status.INTERNAL_SERVER_ERROR.toString() + " : " + LoggerUtility.createErrorMessage(e));

            }
        } else {
            try {
                List<Concept> cList = new ArrayList<>();
                cList.addAll(CSnoServResource.agent.getAllDescendantConcepts(id.trim()));
                jsonString = CSnoServResource.gson.toJson(cList);
            } catch (Exception e) // caches any of the service exceptions
            {
                // Log the Exception
                logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
                return CORSHeaderSupport.addCORSHeader(Response.Status.INTERNAL_SERVER_ERROR,Response.Status.INTERNAL_SERVER_ERROR.toString() + " : " + LoggerUtility.createErrorMessage(e));

            }

        }
        // if callback in URL and is not just the "?" (e.g. from local-host)
        if (callback != null && callback.length() > 1) {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,callback + "(" + jsonString + ");");
        } else {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,jsonString);
        }
    }

    /**
     * Returns all refsets
     *
     * @param callback {@link String} name of the callback function in a JSON
     *                 request</br>
     *                 (for allowing cross domain request)
     */
    @GET
    @Produces({ MediaType.APPLICATION_JSON + ";charset=utf-8" })
    @Path("/refset")
    public Response getAllRefsets(@QueryParam("callback") String callback) {
        CSnoServResource.initProperties();
        Logger logger = LogManager.getLogger(CSnoServResource.class);
        String jsonString = "";
        try {
            Set<Refset> refsetList = null;
            List<Concept> refset = new ArrayList<>();
            refsetList = CSnoServResource.agent.getAllRefset();
            for (Refset r : refsetList) {
                refset.add(r.getRefsetConcept());
            }
            jsonString = CSnoServResource.gson.toJson(refset);
            JsonArray jsonarr = CSnoServResource.gson.fromJson(jsonString, JsonArray.class);
            for (int i = 0; i < jsonarr.size(); i++) {
                JsonObject jsnObj = (JsonObject) jsonarr.get(i);
                String jsnConceptId = jsnObj.get(Constants.ID).toString();
                String jsonConceptId = jsnConceptId.substring(1, jsnConceptId.length() - 1);
                for (Refset r : refsetList) {
                    String refsetid = r.getRefsetConcept().getId();
                    if (refsetid.equalsIgnoreCase(jsonConceptId)) {
                        jsnObj.addProperty("count", r.getRefsetCount());
                    }
                }


            }
            jsonString = CSnoServResource.gson.toJson(jsonarr);

        } catch (Exception e) // catches any of the service exceptions
        {
            // Log the Exception
            logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
            return CORSHeaderSupport.addCORSHeader(Response.Status.INTERNAL_SERVER_ERROR,Response.Status.INTERNAL_SERVER_ERROR.toString() + " : " + LoggerUtility.createErrorMessage(e));

        }
        // if callback in URL and is not just the "?" (e.g. from local-host)
        if (callback != null && callback.length() > 1) {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,callback + "(" + jsonString + ");");
        } else {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,jsonString);
        }
    }

    /**
     * Returns all imported extensions
     *
     * @param callback {@link String} name of the callback function in a JSON
     *                 request</br>
     *                 (for allowing cross domain request)
     */
    @GET
    @Produces({ MediaType.APPLICATION_JSON + ";charset=utf-8" })
    @Path("/extension")
    public Response getAllExtensions(@QueryParam("callback") String callback) {
        CSnoServResource.initProperties();
        Logger logger = LogManager.getLogger(CSnoServResource.class);
        String jsonString = "";
        try {
            Set<Refset> refsetList = null;
            List<Concept> refset = new ArrayList<>();
            refsetList = CSnoServResource.agent.getAllExtension();
            for (Refset r : refsetList) {
                refset.add(r.getRefsetConcept());
            }
            jsonString = CSnoServResource.gson.toJson(refset);
            JsonArray jsonarr = CSnoServResource.gson.fromJson(jsonString, JsonArray.class);
            for (int i = 0; i < jsonarr.size(); i++) {
                JsonObject jsnObj = (JsonObject) jsonarr.get(i);
                String jsnConceptId = jsnObj.get(Constants.ID).toString();
                String jsonConceptId = jsnConceptId.substring(1, jsnConceptId.length() - 1);
                for (Refset r : refsetList) {
                    String refsetid = r.getRefsetConcept().getId();
                    if (refsetid.equalsIgnoreCase(jsonConceptId)) {
                        jsnObj.addProperty("count", r.getRefsetCount());
                    }
                }


            }
            jsonString = CSnoServResource.gson.toJson(jsonarr);

        } catch (Exception e) // catches any of the service exceptions
        {
            // Log the Exception
            logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
            return CORSHeaderSupport.addCORSHeader(Response.Status.INTERNAL_SERVER_ERROR,Response.Status.INTERNAL_SERVER_ERROR.toString() + " : " + LoggerUtility.createErrorMessage(e));

        }
        // if callback in URL and is not just the "?" (e.g. from local-host)
        if (callback != null && callback.length() > 1) {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,callback + "(" + jsonString + ");");
        } else {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,jsonString);
        }
    }

    /**
     * Returns all REFSET members corresponding to a REFSET
     *
     * @param refsetid {@link String} identifier of REFSET.
     * @param callback {@link String} name of the callback function in a JSON
     *                 request</br>
     *                 (for allowing cross domain request)
     */
    @GET
    @Produces({ MediaType.APPLICATION_JSON + ";charset=utf-8" })
    @Path("/refset/members")
    public Response getAllRefsetMembers(@QueryParam("refsetid") String refsetid,
                                        @QueryParam("callback") String callback) {

        CSnoServResource.initProperties();
        Logger logger = LogManager.getLogger(CSnoServResource.class);

        if (refsetid == null || refsetid.equalsIgnoreCase("")) {
            logger.error(LoggerUtility.Exception, "Invalid Query Parameter Value: refsetid: {}" , refsetid);
            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());
        }

        String jsonString;
        try {

            refsetid = java.net.URLDecoder.decode(refsetid, UTF_8);
            Set<Concept> list = CSnoServResource.agent.getRefsetMember(refsetid);

            jsonString = CSnoServResource.gson.toJson(list);

        } catch (Exception e) // catches any of the service exceptions
        {
            // Log the Exception
            logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
            return CORSHeaderSupport.addCORSHeader(Response.Status.INTERNAL_SERVER_ERROR,Response.Status.INTERNAL_SERVER_ERROR.toString() + " : " + LoggerUtility.createErrorMessage(e));

        }
        // if callback in URL and is not just the "?" (e.g. from localhost)
        if (callback != null && callback.length() > 1) {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,callback + "(" + jsonString + ");");
        } else {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,jsonString);
        }
    }

    /**
     * Returns all EXTENSION members corresponding to an EXTENSION
     *
     * @param moduleId {@link String} identifier of EXTENSION.
     * @param callback {@link String} name of the callback function in a JSON
     *                 request</br>
     *                 (for allowing cross domain request)
     */
    @GET
    @Produces({ MediaType.APPLICATION_JSON + ";charset=utf-8" })
    @Path("/extension/members")
    public Response getAllExtensionMembers(@QueryParam("moduleid") String moduleId, @DefaultValue("1") @QueryParam("page") String pageNumber,
                                           @QueryParam("callback") String callback) {

        CSnoServResource.initProperties();
        Logger logger = LogManager.getLogger(CSnoServResource.class);

        if (moduleId == null || moduleId.equalsIgnoreCase("") || !moduleId.matches(_0_9)) {
            logger.error(LoggerUtility.Exception, "Invalid Query Parameter Value: moduleId: {}" , moduleId);
            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());
        }

        if (!pageNumber.matches(_0_9)) {
            logger.error(LoggerUtility.Exception, "Invalid Query Parameter Value: page: {}" , pageNumber);
            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());
        }

        String jsonString;
        try {

            moduleId = java.net.URLDecoder.decode(moduleId, UTF_8);
            Set<Concept> list = CSnoServResource.agent.getExtensionMember(moduleId, Integer.parseInt(pageNumber));

            jsonString = CSnoServResource.gson.toJson(list);

        } catch (Exception e) // catches any of the service exceptions
        {
            // Log the Exception
            logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
            return CORSHeaderSupport.addCORSHeader(Response.Status.INTERNAL_SERVER_ERROR,Response.Status.INTERNAL_SERVER_ERROR.toString() + " : " + LoggerUtility.createErrorMessage(e));

        }
        // if callback in URL and is not just the "?" (e.g. from localhost)
        if (callback != null && callback.length() > 1) {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,callback + "(" + jsonString + ");");
        } else {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,jsonString);
        }
    }



    /**
     * Returns all parent concepts of concept
     *
     * @param id       {@link String} concept id for which lookup is to be done
     * @param callback {@link String} name of the callback function in a jsonp
     *                 request</br>
     *                 (for allowing cross domain request)
     */
    @GET
    @Produces({ MediaType.APPLICATION_JSON + ";charset=utf-8" })
    @Path("/parents")
    public Response getParents(@QueryParam("id") String id, @QueryParam("callback") String callback) {

        CSnoServResource.initProperties();
        Logger logger = LogManager.getLogger(CSnoServResource.class);

        if (id == null || id.equalsIgnoreCase("") || !id.matches(_0_9)) {
            logger.error(LoggerUtility.Exception, INVALID_QUERY_PARAMETER_VALUE_ID , id);

            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());
        }

        String jsonString;
        try {
            jsonString = CSnoServResource.gson.toJson(CSnoServResource.agent.getRelations(id.trim(), EnumRelationshipType.IS_A.getValue(), EnumDirection.SOURCE));
        } catch (Exception e) // caches any of the service exceptions
        {
            // Log the Exception
            logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
            return CORSHeaderSupport.addCORSHeader(Response.Status.INTERNAL_SERVER_ERROR,
                    Response.Status.INTERNAL_SERVER_ERROR.toString() + " : " + LoggerUtility.createErrorMessage(e));

        }
        // if callback in URL and is not just the "?" (e.g. from localhost)
        if (callback != null && callback.length() > 1) {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,callback + "(" + jsonString + ");");
        } else {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,jsonString);
        }
    }

    /**
     * Returns all immediate child concepts of concept
     *
     * @param id       {@link String} concept id for which lookup is to be done
     * @param callback {@link String} name of the callback function in a jsonp
     *                 request</br>
     *                 (for allowing cross domain request)
     */
    @GET
    @Produces({ MediaType.APPLICATION_JSON + ";charset=utf-8" })
    @Path("/children")
    public Response getChildConcepts(@QueryParam("id") String id, @QueryParam("callback") String callback) {

        CSnoServResource.initProperties();
        Logger logger = LogManager.getLogger(CSnoServResource.class);

        if (id == null || id.equalsIgnoreCase("") || !id.matches(_0_9)) {
            logger.error(LoggerUtility.Exception, INVALID_QUERY_PARAMETER_VALUE_ID , id);
            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());
        }

        String jsonString;
        try {
            jsonString = CSnoServResource.gson
                    .toJson(CSnoServResource.agent.getRelations(id.trim(), EnumRelationshipType.IS_A.getValue(), EnumDirection.DESTINATION));
        } catch (Exception e) // caches any of the service exceptions
        {
            // Log the Exception
            logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
            return CORSHeaderSupport.addCORSHeader(Response.Status.INTERNAL_SERVER_ERROR,
                    Response.Status.INTERNAL_SERVER_ERROR.toString() + " : " + LoggerUtility.createErrorMessage(e));

        }
        // if callback in URL and is not just the "?" (e.g. from localhost)
        if (callback != null && callback.length() > 1) {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,callback + "(" + jsonString + ");");
        } else {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,jsonString);
        }
    }

    /**
     * Return response after parsing ECL query.
     *
     * @param query {@link String} ECL query.
     * @param term Filter result based on given {@link String}.
     * @param callback       {@link String} name of the callback function in a json
     *                       request</br>
     *                       (for allowing cross domain request)
     */
    @GET
    @Produces({ MediaType.APPLICATION_JSON + ";charset=utf-8" })
    @Consumes({ MediaType.APPLICATION_FORM_URLENCODED })
    @Path("/ecl")
    public Response executeEcl(@QueryParam("query") String query,
                               @DefaultValue("") @QueryParam("term") String term,
                               @DefaultValue("false") @QueryParam("returnAll") boolean returnAll,
                               @QueryParam("callback") String callback) {
        CSnoServResource.initProperties();
        String jsonString = "";
        int totalConcepts = 0;
        try {
            Set<Concept> eclQueryResponseConcepts = new HashSet<>(CSnoServResource.agent.executeEcl(query,term));
            totalConcepts = eclQueryResponseConcepts.size();
            if(!returnAll && (totalConcepts > 100)) {
                eclQueryResponseConcepts = eclQueryResponseConcepts.stream().limit(100).collect(Collectors.toSet());
            }
            ConceptTotalDTO eclResponse = new ConceptTotalDTO(totalConcepts, eclQueryResponseConcepts);
            jsonString = CSnoServResource.gson.toJson(eclResponse);
        } catch (Exception e) { // catches any of the service exceptions
            // Log the Exception
            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST, e.getMessage());
        }
        

        // if callback in URL and is not just the "?" (e.g. from local-host)
        if (callback != null && callback.length() > 1) {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK, callback + "(" + jsonString + ");");
        } else {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK, jsonString);
        }
    }



    @GET
    @Produces({ MediaType.APPLICATION_JSON + ";charset=utf-8" })
    @Consumes({ MediaType.APPLICATION_FORM_URLENCODED })
    @Path("/concept")
    public Response getAllConcept(@QueryParam("attribute") String attributename,
                                  @DefaultValue("0") @QueryParam("destinationid") String destinationId,
                                  @DefaultValue("all") @QueryParam("semantictag") String semantictag,
                                  @DefaultValue("false") @QueryParam("subsumption") boolean subsumption,
                                  @DefaultValue("null") @QueryParam("parentid") String parentId,
                                  @DefaultValue("false") @QueryParam("excludeparentconcept") boolean excludeparentconcept,
                                  @QueryParam("callback") String callback) {
        CSnoServResource.initProperties();
        Logger logger = LogManager.getLogger(CSnoServResource.class);
        List<String> semanticTagList = null;
        List<String>relationTypeSet=CSnoServResource.agent.getRelationShipType();
        if(!relationTypeSet.contains(attributename.trim().toLowerCase()) && !attributename.toLowerCase().equals(EnumRelationshipType.IS_A.getValue())) {//null==EnumRelationshipType.getEnumForValue(attribute))
            logger.error(LoggerUtility.Exception, "Invalid Query Parameter Value: attributeName: {}" , attributename);
            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());

        }

        if (!destinationId.matches(_0_9)) {
            logger.error(LoggerUtility.Exception, INVALID_QUERY_PARAMETER_VALUE_ID , destinationId);
            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());
        }
        if (semantictag != null) {
            try {
                semantictag = java.net.URLDecoder.decode(semantictag, UTF_8);
                semanticTagList = Arrays.asList(semantictag.split("\\s{2}"));

                // remove empty elements and convert others to lowercase
                Iterator<String> semanticTagIterator = semanticTagList.iterator();
                while (semanticTagIterator.hasNext()) {
                    if (semanticTagIterator.next().isEmpty())
                        semanticTagIterator.remove();
                    else
                        semanticTagIterator.toString().trim().toLowerCase();
                }
                semanticTagList = new ArrayList<>(semanticTagList);

                // get indexed semantic tag from sem index dir
                Set<String> semanticTagSet = CSnoServResource.agent.getSemanticTags();
                // replace snomed rt ctv3 to snomed rt+ctv3
                if (semanticTagList.contains("snomed rt ctv3")) {
                    semanticTagList.remove("snomed rt ctv3");
                    semanticTagList.add("snomed rt+ctv3");
                }
                // validate semantic tags
                if (!semanticTagSet.containsAll(semanticTagList)) {
                    // identify wrong semantic tag
                    for (String semanticTag : semanticTagList) {
                        if (!semanticTagSet.contains(semanticTag) && !semanticTag.equalsIgnoreCase(EnumSemanticTag.ALL.getValue())) {
                          
                                throw new IllegalArgumentException();
                        
                    }

                }
            }} catch (IllegalArgumentException e) {
                logger.error(LoggerUtility.Exception, "Invalid Query Parameter Value: semanticTagList: {}" , semanticTagList);
                return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());
            } catch (UnsupportedEncodingException e) {
                logger.error(LoggerUtility.Exception, "Invalid Query Parameter Value: semanticTagList: {}" , semanticTagList);
                return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());
            }
        
        }

        //Parent ID
        List<String> parentIdList = new ArrayList<>();
        try {
            if (parentId != null) {
                parentId = java.net.URLDecoder.decode(parentId, UTF_8);
                parentIdList = Arrays.asList(parentId.split("\\s{2}"));

                if (parentId.equalsIgnoreCase("null")) {
                    parentIdList = null;
                    parentId = null;
                }

                if (parentId != null) {
                    for (String pId : parentIdList) {
                        if (!pId.matches(_0_9)) {
                            logger.error(LoggerUtility.Exception, "Invalid Query Parameter Value: parentId: {}" , parentId);
                            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,
                                    Response.Status.BAD_REQUEST.toString());
                        }
                    }
                }
            }
        } catch (Exception e) // caches any of the service exceptions
        {
            // Log the Exception
            logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());
        }

        if (destinationId.equals("0"))
            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString() + " : " + "destinationid is required");

        String jsonString;
        try {
            List<Relationship> lstAttribute = CSnoServResource.agent.getConcepts(attributename, semanticTagList, destinationId, subsumption, parentIdList, excludeparentconcept);
            if (lstAttribute != null)
                jsonString = CSnoServResource.gson.toJson(lstAttribute);
            else
                jsonString = CSnoServResource.gson.toJson(Collections.emptyList());
        } catch (Exception e) { // caches any of the service exceptions
            // Log the Exception
            logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
            return CORSHeaderSupport.addCORSHeader(Response.Status.INTERNAL_SERVER_ERROR,
                    Response.Status.INTERNAL_SERVER_ERROR.toString() + " : " + LoggerUtility.createErrorMessage(e));
        }
        // if callback in URL and is not just the "?" (e.g. from localhost)
        if (callback != null && callback.length() > 1) {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,callback + "(" + jsonString + ");");
        } else {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,jsonString);
        }
    }

    /**
     * Returns all ancestor of concept
     *
     * @param id       {@link String} concept id for which lookup is to be done
     * @param callback {@link String} name of the callback function in a jsonp
     *                 request</br>
     *                 (for allowing cross domain request)
     */
    /*
     * @GET
     *
     * @Produces({ MediaType.APPLICATION_JSON + ";charset=utf-8" })
     *
     * @Path("explore/allancestor")
     */
    public Response getAllConceptParent(@QueryParam("id") String id, @QueryParam("count") Boolean count,
                                        @QueryParam("callback") String callback) {
        CSnoServResource.initProperties();
        Logger logger = LogManager.getLogger(CSnoServResource.class);
        logger.info(LoggerUtility.CONSOLE, "get called");

        if (id == null || id.equalsIgnoreCase("") || !id.matches(_0_9)) {
            logger.error(LoggerUtility.Exception, INVALID_QUERY_PARAMETER_VALUE_ID , id);
            return CORSHeaderSupport.addCORSHeader(Response.Status.BAD_REQUEST,Response.Status.BAD_REQUEST.toString());
        }

        String jsonString;
        if (count != null && count) {
            try {

                jsonString = CSnoServResource.gson.toJson(CSnoServResource.agent.getAllAncestorConcepts(id.trim()));
            } catch (Exception e) // caches any of the service exceptions
            {
                // Log the Exception
                logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
                return CORSHeaderSupport.addCORSHeader(Response.Status.INTERNAL_SERVER_ERROR,
                        Response.Status.INTERNAL_SERVER_ERROR.toString() + " : " + LoggerUtility.createErrorMessage(e));

            }
        } else {
            try {
                List<Concept> cList = new ArrayList<>();
                cList.addAll(CSnoServResource.agent.getAllAncestorConcepts(id.trim()));
                jsonString = CSnoServResource.gson.toJson(cList);
            } catch (Exception e) // caches any of the service exceptions
            {
                // Log the Exception
                logger.error(LoggerUtility.Exception, LoggerUtility.createErrorMessage(e));
                return CORSHeaderSupport.addCORSHeader(Response.Status.INTERNAL_SERVER_ERROR,Response.Status.INTERNAL_SERVER_ERROR.toString() + " : " + LoggerUtility.createErrorMessage(e));

            }

        }
        // if callback in URL and is not just the "?" (e.g. from local-host)
        if (callback != null && callback.length() > 1) {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,callback + "(" + jsonString + ");");
        } else {
            return CORSHeaderSupport.addCORSHeader(Response.Status.OK,jsonString);
        }
    }

}