/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.apache.usergrid.rest.applications;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.jaxrs.json.annotation.JSONP;
import org.apache.amber.oauth2.common.error.OAuthError;
import org.apache.amber.oauth2.common.exception.OAuthProblemException;
import org.apache.amber.oauth2.common.message.OAuthResponse;
import org.apache.amber.oauth2.common.message.types.GrantType;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.codec.Base64;
import org.apache.usergrid.management.ApplicationInfo;
import org.apache.usergrid.management.exceptions.DisabledAdminUserException;
import org.apache.usergrid.management.exceptions.DisabledAppUserException;
import org.apache.usergrid.management.exceptions.UnactivatedAdminUserException;
import org.apache.usergrid.management.exceptions.UnactivatedAppUserException;
import org.apache.usergrid.mq.QueueManager;
import org.apache.usergrid.persistence.EntityManager;
import org.apache.usergrid.persistence.SimpleEntityRef;
import org.apache.usergrid.persistence.entities.Application;
import org.apache.usergrid.persistence.entities.User;
import org.apache.usergrid.persistence.exceptions.EntityNotFoundException;
import org.apache.usergrid.persistence.index.query.Identifier;
import org.apache.usergrid.rest.AbstractContextResource;
import org.apache.usergrid.rest.ApiResponse;
import org.apache.usergrid.rest.applications.assets.AssetsResource;
import org.apache.usergrid.rest.applications.events.EventsResource;
import org.apache.usergrid.rest.applications.kvm.KvmResource;
import org.apache.usergrid.rest.applications.queues.QueueResource;
import org.apache.usergrid.rest.applications.users.UsersResource;
import org.apache.usergrid.rest.exceptions.AuthErrorInfo;
import org.apache.usergrid.rest.exceptions.RedirectionException;
import org.apache.usergrid.rest.exceptions.UnsupportedRestOperationException;
import org.apache.usergrid.rest.security.annotations.RequireApplicationAccess;
import org.apache.usergrid.rest.security.annotations.RequireOrganizationAccess;
import org.apache.usergrid.security.oauth.AccessInfo;
import org.apache.usergrid.security.oauth.ClientCredentialsInfo;
import org.glassfish.jersey.server.mvc.Viewable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.ws.rs.*;
import javax.ws.rs.core.*;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.UUID;

import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.apache.commons.lang.StringUtils.isNotBlank;
import static org.apache.usergrid.rest.exceptions.SecurityException.mappableSecurityException;
import static org.apache.usergrid.security.oauth.ClientCredentialsInfo.getUUIDFromClientId;
import static org.apache.usergrid.security.shiro.utils.SubjectUtils.isApplicationAdmin;
import static org.apache.usergrid.services.ServiceParameter.addParameter;
import static org.apache.usergrid.utils.StringUtils.stringOrSubstringAfterFirst;
import static org.apache.usergrid.utils.StringUtils.stringOrSubstringBeforeFirst;


@Component("org.apache.usergrid.rest.applications.ApplicationResource")
@Scope("prototype")
@Produces({
        MediaType.APPLICATION_JSON, "application/javascript", "application/x-javascript", "text/ecmascript",
        "application/ecmascript", "text/jscript"
})
public class ApplicationResource extends CollectionResource {

    public static final Logger logger = LoggerFactory.getLogger( ApplicationResource.class );

    UUID applicationId;
    QueueManager queues;


    public ApplicationResource() {
    }


    public ApplicationResource init( UUID applicationId ) throws Exception {
        this.applicationId = applicationId;
        services = smf.getServiceManager( applicationId );
        queues = qmf.getQueueManager( applicationId );
        return this;
    }


    public QueueManager getQueues() {
        return queues;
    }


    @Override
    public UUID getApplicationId() {
        return applicationId;
    }


    @RequireApplicationAccess
    @Path("auth")
    public AuthResource getAuthResource() throws Exception {
        return getSubResource( AuthResource.class );
    }


    @RequireApplicationAccess
    @Path("queues")
    public QueueResource getQueueResource() throws Exception {
        return getSubResource( QueueResource.class ).init( queues, "" );
    }


    @RequireApplicationAccess
    @Path("events")
    public EventsResource getEventsResource( @Context UriInfo ui ) throws Exception {
        addParameter( getServiceParameters(), "events" );

        PathSegment ps = getFirstPathSegment( "events" );
        if ( ps != null ) {
            addMatrixParams( getServiceParameters(), ui, ps );
        }

        return getSubResource( EventsResource.class );
    }


    @RequireApplicationAccess
    @Path("event")
    public EventsResource getEventResource( @Context UriInfo ui ) throws Exception {
        return getEventsResource( ui );
    }

    @RequireApplicationAccess
    @Path("keyvaluemaps")
    public KvmResource getKvmResource(@Context UriInfo ui ) throws Exception {
        return getSubResource( KvmResource.class );
    }


    @RequireApplicationAccess
    @Path("assets")
    public AssetsResource getAssetsResource( @Context UriInfo ui ) throws Exception {
        if (logger.isTraceEnabled()) {
            logger.trace("in assets n applicationResource");
        }
        addParameter( getServiceParameters(), "assets" );

        PathSegment ps = getFirstPathSegment( "assets" );
        if ( ps != null ) {
            addMatrixParams( getServiceParameters(), ui, ps );
        }

        return getSubResource( AssetsResource.class );
    }


    @RequireApplicationAccess
    @Path("asset")
    public AssetsResource getAssetResource( @Context UriInfo ui ) throws Exception {
        // TODO change to singular
        if (logger.isTraceEnabled()) {
            logger.trace("in asset in applicationResource");
        }
        return getAssetsResource( ui );
    }


    @Path("users")
    public UsersResource getUsers( @Context UriInfo ui ) throws Exception {
        if (logger.isTraceEnabled()) {
            logger.trace("ApplicationResource.getUsers");
        }
        addParameter( getServiceParameters(), "users" );

        PathSegment ps = getFirstPathSegment( "users" );
        if ( ps != null ) {
            addMatrixParams( getServiceParameters(), ui, ps );
        }

        return getSubResource( UsersResource.class );
    }


    @Path("user")
    public UsersResource getUsers2( @Context UriInfo ui ) throws Exception {
        return getUsers( ui );
    }


    @GET
    @Path("token")
    public Response getAccessToken( @Context UriInfo ui, @HeaderParam("Authorization") String authorization,
                                    @QueryParam("grant_type") String grant_type,
                                    @QueryParam("username") String username, @QueryParam("password") String password,
                                    @QueryParam("pin") String pin, @QueryParam("client_id") String client_id,
                                    @QueryParam("client_secret") String client_secret, @QueryParam("code") String code,
                                    @QueryParam("ttl") long ttl, @QueryParam("redirect_uri") String redirect_uri,
                                    @QueryParam("callback") @DefaultValue("") String callback ) throws Exception {

        if (logger.isTraceEnabled()) {
            logger.trace("ApplicationResource.getAccessToken");
        }

        User user = null;

        try {

            if ( authorization != null ) {
                String type = stringOrSubstringBeforeFirst( authorization, ' ' ).toUpperCase();
                if ( "BASIC".equals( type ) ) {
                    String token = stringOrSubstringAfterFirst( authorization, ' ' );
                    String[] values = Base64.decodeToString( token ).split( ":" );
                    if ( values.length >= 2 ) {
                        client_id = values[0];
                        client_secret = values[1];
                    }
                }
            }

            // do checking for different grant types
            String errorDescription = "invalid username or password";
            if ( GrantType.PASSWORD.toString().equals( grant_type ) ) {
                try {
                    user = management
                            .verifyAppUserPasswordCredentials( services.getApplicationId(), username, password );
                }
                catch ( UnactivatedAppUserException uaue ) {
                    errorDescription = "user not activated";
                }
                catch ( DisabledAppUserException daue ) {
                    errorDescription = "user disabled";
                }
                catch ( Exception e1 ) {
                    logger.warn( "Unexpected exception during token username/password verification", e1 );

                }
            }
            else if ( "pin".equals( grant_type ) ) {
                try {
                    user = management.verifyAppUserPinCredentials( services.getApplicationId(), username, pin );
                }
                catch ( Exception e1 ) {
                    logger.warn( "Unexpected exception during token pin verification", e1 );

                }
            }
            else if ( "client_credentials".equals( grant_type ) ) {
                try {
                    AccessInfo access_info = management.authorizeClient( client_id, client_secret, ttl );
                    if ( access_info != null ) {
                        return Response.status( SC_OK ).type( jsonMediaType( callback ) )
                                       .entity( wrapWithCallback( access_info, callback ) ).build();
                    }
                }
                catch ( Exception e1 ) {
                    logger.warn( "Unexpected exception during token client authentication", e1 );
                }
            }

            if ( user == null ) {

                if (logger.isDebugEnabled()) {
                    logger.debug("Returning 400 bad request due to: {}", errorDescription);
                }

                OAuthResponse response =
                        OAuthResponse.errorResponse( SC_BAD_REQUEST ).setError( OAuthError.TokenResponse.INVALID_GRANT )
                                     .setErrorDescription( errorDescription ).buildJSONMessage();
                return Response.status( response.getResponseStatus() ).type( jsonMediaType( callback ) )
                               .entity( wrapWithCallback( response.getBody(), callback ) ).build();
            }

            String token = management.getAccessTokenForAppUser( services.getApplicationId(), user.getUuid(), ttl );

            AccessInfo access_info =
                    new AccessInfo().withExpiresIn( tokens.getMaxTokenAgeInSeconds( token ) ).withAccessToken( token )
                                    .withProperty( "user", user );

            return Response.status( SC_OK ).type( jsonMediaType( callback ) )
                           .entity( wrapWithCallback( access_info, callback ) ).build();
        }
        catch ( OAuthProblemException e ) {
            logger.error( "OAuth Error", e );
            OAuthResponse res = OAuthResponse.errorResponse( SC_BAD_REQUEST ).error( e ).buildJSONMessage();
            return Response.status( res.getResponseStatus() ).type( jsonMediaType( callback ) )
                           .entity( wrapWithCallback( res.getBody(), callback ) ).build();
        }
    }


    @POST
    @Path("token")
    @Consumes(APPLICATION_FORM_URLENCODED)
    public Response getAccessTokenPost( @Context UriInfo ui, @HeaderParam("Authorization") String authorization,
                                        @FormParam("grant_type") String grant_type,
                                        @FormParam("username") String username, @FormParam("password") String password,
                                        @FormParam("pin") String pin, @FormParam("client_id") String client_id,
                                        @FormParam("client_secret") String client_secret,
                                        @FormParam("code") String code, @FormParam("ttl") long ttl,
                                        @FormParam("redirect_uri") String redirect_uri,
                                        @QueryParam("callback") @DefaultValue("") String callback ) throws Exception {

        if (logger.isTraceEnabled()) {
            logger.trace("ApplicationResource.getAccessTokenPost");
        }

        return getAccessToken( ui, authorization, grant_type, username, password, pin, client_id, client_secret, code,
                ttl, redirect_uri, callback );
    }


    @POST
    @Path("token")
    @Consumes(APPLICATION_JSON)
    public Response getAccessTokenPostJson( @Context UriInfo ui,
            @HeaderParam("Authorization") String authorization,
            Map<String, Object> json,
            @QueryParam("callback") @DefaultValue("") String callback ) throws Exception {

        String grant_type = ( String ) json.get( "grant_type" );
        String username = ( String ) json.get( "username" );
        String password = ( String ) json.get( "password" );
        String client_id = ( String ) json.get( "client_id" );
        String client_secret = ( String ) json.get( "client_secret" );
        String pin = ( String ) json.get( "pin" );
        String code = ( String ) json.get( "code" );
        String redirect_uri = ( String ) json.get( "redirect_uri" );
        long ttl = 0;

        if ( json.get( "ttl" ) != null ) {
            try {
                ttl = Long.parseLong( json.get( "ttl" ).toString() );
            }
            catch ( NumberFormatException nfe ) {
                throw new IllegalArgumentException( "ttl must be a number >= 0" );
            }
        }

        return getAccessToken( ui, authorization, grant_type, username, password, pin, client_id,
                client_secret, code, ttl, redirect_uri, callback );
    }


    @GET
    @Path("credentials")
    @RequireApplicationAccess
    @JSONP
    @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
    public ApiResponse getKeys( @Context UriInfo ui,
                                    @QueryParam("callback") @DefaultValue("callback") String callback )
            throws Exception {

        if (logger.isTraceEnabled()) {
            logger.trace("AuthResource.keys");
        }

        if ( !isApplicationAdmin( Identifier.fromUUID( applicationId ) ) ) {
            throw new UnauthorizedException();
        }

        ClientCredentialsInfo kp =
                new ClientCredentialsInfo( management.getClientIdForApplication( services.getApplicationId() ),
                        management.getClientSecretForApplication( services.getApplicationId() ) );

        return   createApiResponse().withCredentials( kp ).withAction( "get application keys" ).withSuccess();
    }


    @POST
    @Path("credentials")
    @RequireApplicationAccess
    @JSONP
    @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
    public ApiResponse generateKeys( @Context UriInfo ui,
        @QueryParam("callback") @DefaultValue("callback") String callback ) throws Exception {

        if (logger.isTraceEnabled()) {
            logger.trace("AuthResource.keys");
        }

        if ( !isApplicationAdmin( Identifier.fromUUID( applicationId ) ) ) {
            throw new UnauthorizedException();
        }

        ClientCredentialsInfo kp = new ClientCredentialsInfo(
            management.getClientIdForApplication( services.getApplicationId() ),
            management.newClientSecretForApplication( services.getApplicationId() ) );

        return createApiResponse().withCredentials( kp ).withAction( "generate application keys" ).withSuccess();
    }


    @GET
    @Path("authorize")
    public Viewable showAuthorizeForm(
            @Context UriInfo ui,
            @QueryParam("response_type") String response_type,
            @QueryParam("client_id") String client_id,
            @QueryParam("redirect_uri") String redirect_uri,
            @QueryParam("scope") String scope,
            @QueryParam("state") String state ) {

        try {
            UUID uuid = getUUIDFromClientId( client_id );
            if ( uuid == null ) {
                throw mappableSecurityException( AuthErrorInfo.OAUTH2_INVALID_CLIENT,
                        "Unable to authenticate (OAuth). Invalid client_id" );
            }

            responseType = response_type;
            clientId = client_id;
            redirectUri = redirect_uri;
            this.scope = scope;
            this.state = state;

            ApplicationInfo app = management.getApplicationInfo( applicationId );
            applicationName = app.getName();

            return handleViewable( "authorize_form", this, getOrganizationName() );
        }
        catch ( RedirectionException e ) {
            throw e;
        }
        catch ( Exception e ) {
            return handleViewable( "error", e, getOrganizationName() );
        }
    }


    @POST
    @Path("authorize")
    @Produces(MediaType.TEXT_HTML)
    public Response handleAuthorizeForm( @Context UriInfo ui,
            @FormParam("response_type") String response_type,
            @FormParam("client_id") String client_id,
            @FormParam("redirect_uri") String redirect_uri,
            @FormParam("scope") String scope, @FormParam("state") String state,
            @FormParam("username") String username,
            @FormParam("password") String password ) {

        if (logger.isTraceEnabled()) {
            logger.trace("ApplicationResource /authorize: {}/{}", username, password);
        }

        try {
            responseType = response_type;
            clientId = client_id;
            redirectUri = redirect_uri;
            this.scope = scope;
            this.state = state;

            User user = null;
            String errorDescription = "Username or password do not match";
            try {
                user = management.verifyAppUserPasswordCredentials( services.getApplicationId(), username, password );
            }
            catch ( UnactivatedAdminUserException uaue ) {
                errorDescription = "user not activated";
            }
            catch ( DisabledAdminUserException daue ) {
                errorDescription = "user disabled";
            }
            catch ( Exception e1 ) {
                logger.warn("Unexpected exception in authorize username/password verification", e1);
            }

            if ( ( user != null ) && isNotBlank( redirect_uri ) ) {
                String authorizationCode =
                        management.getAccessTokenForAppUser( services.getApplicationId(), user.getUuid(), 0 );
                redirect_uri = buildRedirectUriWithAuthCode( redirect_uri, state, authorizationCode );

                throw new RedirectionException( redirect_uri );
            }
            else {
                errorMsg = errorDescription;
            }

            ApplicationInfo app = management.getApplicationInfo( applicationId );
            applicationName = app.getName();

            return Response.ok( handleViewable( "authorize_form", this, getOrganizationName() ) ).build() ;
        }
        catch ( RedirectionException e ) {
            throw e;
        }
        catch ( Exception e ) {
            logger.error("handleAuthorizeForm failed", e);
            return Response.ok( handleViewable( "error", this, getOrganizationName() ) ).build() ;
        }
    }


    @Override
    @DELETE
    @RequireOrganizationAccess
    public ApiResponse executeDelete( @Context final UriInfo ui, @DefaultValue( "callback" ) final String callback,
                                          final String confirmAppDelete ) throws Exception {
        throw new UnsupportedRestOperationException( "Delete must be done from the management endpoint" );
    }


    String errorMsg = "";
    String applicationName;
    String responseType;
    String clientId;
    String redirectUri;
    String scope;
    String state;


    public String getErrorMsg() {
        return errorMsg;
    }


    public String getApplicationName() {
        return applicationName;
    }


    public String getResponseType() {
        return responseType;
    }


    public String getClientId() {
        return clientId;
    }


    public String getRedirectUri() {
        return redirectUri;
    }


    public String getScope() {
        return scope;
    }


    public String getState() {
        return state;
    }


    // todo: find a mechanism to move these methods into the push notifications
    // project
    @RequireApplicationAccess
    @Path("notifiers")
    public AbstractContextResource getNotifiersResource( @Context UriInfo ui ) throws Exception {

        Class cls = Class.forName( "org.apache.usergrid.rest.applications.notifiers.NotifiersResource" );

        if (logger.isTraceEnabled()) {
            logger.trace("NotifiersResource.getNotifiersResource");
        }
        addParameter( getServiceParameters(), "notifiers" );

        PathSegment ps = getFirstPathSegment( "notifiers" );
        if ( ps != null ) {
            addMatrixParams( getServiceParameters(), ui, ps );
        }

        return getSubResource( cls );
    }


    @RequireApplicationAccess
    @Path("notifier")
    public AbstractContextResource getNotifierResource( @Context UriInfo ui ) throws Exception {
        return getNotifiersResource( ui );
    }


    private String buildRedirectUriWithAuthCode( String redirect_uri, String state, String authorizationCode )
            throws UnsupportedEncodingException {
        if ( !redirect_uri.contains( "?" ) ) {
            redirect_uri += "?";
        }
        else {
            redirect_uri += "&";
        }
        redirect_uri += "code=" + authorizationCode;

        if ( isNotBlank( state ) ) {
            redirect_uri += "&state=" + URLEncoder.encode( state, "UTF-8" );
        }

        return redirect_uri;
    }


    //mAX /APM integration
    public static final String APIGEE_MOBILE_APM_CONFIG_JSON_KEY = "apigeeMobileConfig";


    @GET
    @Path("apm/apigeeMobileConfig")
    @JSONP
    @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
    public Object getAPMConfig( @Context UriInfo ui,
                                         @QueryParam("callback") @DefaultValue("callback") String callback )
            throws Exception {
        EntityManager em = emf.getEntityManager( applicationId );
        Object value = em.getProperty( new SimpleEntityRef( Application.ENTITY_TYPE, applicationId ),
                APIGEE_MOBILE_APM_CONFIG_JSON_KEY );
        //If there is no apm configuration then try to create apm config on the fly
        if ( value == null ) {
            value = management.registerAppWithAPM(
                management.getOrganizationForApplication( applicationId ),
                management.getApplicationInfo( applicationId )
            );
        }
        if(value==null){
            throw new EntityNotFoundException("apigeeMobileConfig not found, it is possibly not enabled for your config.");
        }
        return value;
    }

    // Specifically require superuser access as this is setting app properties directly (only way to currently do this
    // with Apigee's apigeeMobileConfig
    @RequireOrganizationAccess
    @POST
    @Path("apm/apigeeMobileConfig")
    @Consumes(APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public String setAPMConfig( @Context UriInfo ui,
                                @QueryParam( "callback" ) @DefaultValue( "callback" ) String callback,
                                Map<String, Object> json ) throws Exception {

        if(json == null || json.size() < 1){
            logger.error("Param {} cannot be null for POST apm/apigeeMobileConfig", APIGEE_MOBILE_APM_CONFIG_JSON_KEY);
            throw new IllegalArgumentException("Request body cannot be empty and must include apigeeMobileConfig params");
        }

        final String requestAppUUID = (String) json.get("applicationUUID");
        if(!requestAppUUID.equalsIgnoreCase(applicationId.toString())){
            logger.error("Provided application UUID {} does not match actual application UUID {}",
                requestAppUUID,
                applicationId.toString());
            throw new IllegalArgumentException(
                String.format("Provided application UUID %s does not match actual application UUID %s",
                requestAppUUID,
                applicationId.toString())
            );
        }

        final String apmConfig = new ObjectMapper().writeValueAsString(json);

        if(logger.isDebugEnabled()){
            logger.debug("Received request to set apigeeMobileConfig properties with: {}", apmConfig);
        }

        EntityManager em = emf.getEntityManager( applicationId );

        em.setProperty(new SimpleEntityRef(Application.ENTITY_TYPE, applicationId),
            APIGEE_MOBILE_APM_CONFIG_JSON_KEY,
            apmConfig
        );

        logger.info("Successfully set apigeeMobileConfig properties with: {}", apmConfig);

        return apmConfig;

    }


}
