/*
 * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.wso2.carbon.identity.oauth.endpoint.oidcdiscovery;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.base.ServerConfigurationException;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.discovery.OIDCDiscoveryEndPointException;
import org.wso2.carbon.identity.discovery.OIDCProcessor;
import org.wso2.carbon.identity.discovery.builders.OIDProviderResponseBuilder;
import org.wso2.carbon.identity.oauth.common.OAuthConstants;
import org.wso2.carbon.identity.oauth.endpoint.oidcdiscovery.impl.OIDProviderJSONResponseBuilder;
import org.wso2.carbon.identity.oauth.endpoint.util.EndpointUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;

@Path("/oidcdiscovery")
public class OIDCDiscoveryEndpoint {

    private static final Log log = LogFactory.getLog(OIDCDiscoveryEndpoint.class);

    @GET
    @Path("/.well-known/openid-configuration")
    @Produces("application/json")
    public Response getOIDProviderConfiguration(@Context HttpServletRequest request) {

        String tenantDomain = null;
        Object tenantObj = IdentityUtil.threadLocalProperties.get().get(OAuthConstants.TENANT_NAME_FROM_CONTEXT);
        if (tenantObj != null){
            tenantDomain = (String) tenantObj;
        }
        if (StringUtils.isEmpty(tenantDomain)){
            tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
        }

        return this.getResponse(request, tenantDomain);
    }

    private Response getResponse(HttpServletRequest request, String tenant) {
        String response;
        OIDCProcessor processor = EndpointUtil.getOIDCService();
        try {
            OIDProviderResponseBuilder responseBuilder = new OIDProviderJSONResponseBuilder();
            response = responseBuilder.getOIDProviderConfigString(processor.getResponse(request, tenant));
        } catch (OIDCDiscoveryEndPointException e) {
            Response.ResponseBuilder errorResponse = Response.status(processor.handleError(e));
            return errorResponse.entity(e.getMessage()).build();
        } catch (ServerConfigurationException e) {
            log.error("Server Configuration error occured.", e);
            Response.ResponseBuilder errorResponse = Response.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return errorResponse.entity("Error in reading configuration.").build();
        }
        Response.ResponseBuilder responseBuilder = Response.status(HttpServletResponse.SC_OK);
        return responseBuilder.entity(response).build();
    }
}

@@ -1457,16 +1457,52 @@
 tUtil;%0A%0A
+import java.net.URISyntaxException;%0A
 import j
@@ -1765,30 +1765,186 @@
 se;%0A
-%0A@Path(%22/oidcdiscovery
+import javax.ws.rs.core.UriInfo;%0A%0Aimport static org.wso2.carbon.identity.oauth2.util.OAuth2Util.OAuthURL.getOidcDiscoveryEPUrl;%0A%0A@Path(%22/%7Bissuer%7D/.well-known/openid-configuration
 %22)%0Ap
@@ -2207,46 +2207,262 @@
 on(@
-Context HttpServletRequest request) %7B%0A
+PathParam(%22issuer%22) String tokenEp, @Context HttpServletRequest request%0A            , @Context UriInfo uriInfo) %7B%0A%0A        String issuer = null;%0A        if (StringUtils.isNotEmpty(tokenEp)) %7B%0A            issuer = uriInfo.getBaseUri() + tokenEp;%0A        %7D
 %0A   
@@ -2638,16 +2638,17 @@
 != null)
+ 
 %7B%0A      
@@ -2744,16 +2744,17 @@
 Domain))
+ 
 %7B%0A      
@@ -2835,64 +2835,1078 @@
   %7D%0A
-%0A        return this.getResponse(request, tenantDomain);
+         /*  %5Bhttps://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery%5D%0A             %22OpenID Providers supporting Discovery MUST make a JSON document available at the path formed by%0A             concatenating the string /.well-known/openid-configuration to the Issuer.%22*/%0A        try %7B%0A            if (getOidcDiscoveryEPUrl(tenantDomain).equals(issuer)) %7B%0A%0A                return this.getResponse(request, tenantDomain);%0A            %7D else %7B%0A                Response.ResponseBuilder errorResponse = Response.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);%0A                return errorResponse.entity(%22Error while loading the endpoint. The path to the discovery document %22 +%0A                        %22should be in the format of %7Bissuer%7D/.well-known/openid-configuration%22).build();%0A            %7D%0A        %7D catch (URISyntaxException e) %7B%0A            Response.ResponseBuilder errorResponse = Response.status(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);%0A            return errorResponse.entity(%22Error while building the endpoint.%22).build();%0A        %7D
 %0A   
@@ -3983,24 +3983,25 @@
 g tenant) %7B%0A
+%0A
         Stri

Move the OIDC discovery endpoint under the root <issuer>/.well-known/openid-configuration