/*
 * 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.services;


import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.usergrid.persistence.EntityRef;
import org.apache.usergrid.persistence.Query;
import org.apache.usergrid.services.ServiceParameter.QueryParameter;
import org.apache.usergrid.services.ServiceResults.Type;

import org.apache.shiro.SecurityUtils;

import static org.apache.commons.lang.StringUtils.isNotBlank;
import static org.apache.usergrid.utils.ListUtils.isEmpty;
import static org.apache.usergrid.utils.ListUtils.last;


public class ServiceRequest {

    private static final Logger logger = LoggerFactory.getLogger( ServiceRequest.class );

    public static long count = 0;

    private final long id = count++;

    private final ServiceManager services;

    private final ServiceAction action;
    private final ServiceRequest parent;
    private final EntityRef owner;
    private final String serviceName;
    private final String path;
    private final List<ServiceParameter> parameters;
    private final String childPath;
    private final boolean returnsTree;
    private final boolean returnsInboundConnections;
    private final boolean returnsOutboundConnections;
    private final ServicePayload payload;
    private final List<ServiceParameter> originalParameters;
    private final boolean analyzeQueryOnly;
    private final boolean returnQuery;

    // return results_set, result_entity, new_service, param_list, properties


    public ServiceRequest(ServiceManager services, ServiceAction action, String serviceName,
                          List<ServiceParameter> parameters, ServicePayload payload, boolean returnsTree,
                          boolean returnsInboundConnections, boolean returnsOutboundConnections,
                          boolean analyzeQueryOnly, boolean returnQuery) {
        this.services = services;
        this.action = action;
        parent = null;
        owner = services.getApplicationRef();
        childPath = null;
        this.serviceName = serviceName;
        path = "/" + serviceName;
        this.parameters = parameters;
        this.originalParameters = Collections.unmodifiableList( new ArrayList<ServiceParameter>( parameters ) );
        this.returnsTree = returnsTree;
        this.returnsInboundConnections = returnsInboundConnections;
        this.returnsOutboundConnections = returnsOutboundConnections;
        this.analyzeQueryOnly = analyzeQueryOnly;
        this.returnQuery = returnQuery;
        if ( payload == null ) {
            payload = new ServicePayload();
        }

        this.payload = payload;
    }

    public ServiceRequest( ServiceManager services, ServiceAction action, String serviceName,
                           List<ServiceParameter> parameters, ServicePayload payload, boolean returnsTree) {
        this( services, action, serviceName, parameters, payload, returnsTree, true, true, false, false);
    }


    public ServiceRequest( ServiceManager services, ServiceAction action, String serviceName,
                           List<ServiceParameter> parameters, ServicePayload payload ) {
        this( services, action, serviceName, parameters, payload, false, true, true, false, false);
    }


    public ServiceRequest( ServiceRequest parent, EntityRef owner, String path, String childPath, String serviceName,
                           List<ServiceParameter> parameters ) {
        this.services = parent.services;
        this.returnsTree = parent.returnsTree;
        this.returnsInboundConnections = parent.returnsInboundConnections;
        this.returnsOutboundConnections = parent.returnsOutboundConnections;
        this.analyzeQueryOnly = parent.analyzeQueryOnly;
        this.returnQuery = parent.returnQuery;
        this.action = parent.action;
        this.payload = parent.payload;
        this.parent = parent;
        this.owner = owner;
        this.serviceName = serviceName;
        if ( parameters == null ) {
            parameters = new ArrayList<ServiceParameter>();
        }
        this.parameters = parameters;
        this.originalParameters = Collections.unmodifiableList( new ArrayList<ServiceParameter>( parameters ) );
        this.path = path;
        this.childPath = childPath;
    }


    public ServiceRequest( ServiceManager services, ServiceAction action, ServiceRequest parent, EntityRef owner,
                           String path, String childPath, String serviceName, List<ServiceParameter> parameters,
                           ServicePayload payload, boolean returnsTree, boolean returnsInboundConnections,
                           boolean returnsOutboundConnections, boolean analyzeQueryOnly,
                           boolean returnQuery) {
        this.services = services;
        this.action = action;
        this.parent = parent;
        this.owner = owner;
        this.serviceName = serviceName;
        this.path = path;
        this.parameters = parameters;
        this.originalParameters = Collections.unmodifiableList( new ArrayList<ServiceParameter>( parameters ) );
        this.childPath = childPath;
        this.returnsTree = returnsTree;
        this.returnsInboundConnections = returnsInboundConnections;
        this.returnsOutboundConnections = returnsOutboundConnections;
        this.analyzeQueryOnly = analyzeQueryOnly;
        this.returnQuery = returnQuery;
        this.payload = payload;
    }

    public ServiceRequest( ServiceManager services, ServiceAction action, ServiceRequest parent, EntityRef owner,
                           String path, String childPath, String serviceName, List<ServiceParameter> parameters,
                           ServicePayload payload, boolean returnsTree ) {
        this(services, action, parent, owner, path, childPath, serviceName, parameters, payload, returnsTree,
            true, true, false, false);
    }


    public static ServiceRequest withPath( ServiceRequest r, String path ) {
        return new ServiceRequest( r.services, r.action, r.parent, r.owner, path, r.childPath, r.serviceName,
            r.parameters, r.payload, r.returnsTree, r.returnsInboundConnections, r.returnsOutboundConnections,
            r.analyzeQueryOnly, r.returnQuery);
    }


    public static ServiceRequest withChildPath( ServiceRequest r, String childPath ) {
        return new ServiceRequest( r.services, r.action, r.parent, r.owner, r.path, childPath, r.serviceName,
            r.parameters, r.payload, r.returnsTree, r.returnsInboundConnections, r.returnsOutboundConnections,
            r.analyzeQueryOnly, r.returnQuery);
    }


    public ServiceRequest withPath( String path ) {
        return withPath( this, path );
    }


    public ServiceRequest withChildPath( String childPath ) { return withChildPath( this, childPath ); }


    public long getId() {
        return id;
    }


    public String getPath() {
        return path;
    }


    public ServiceAction getAction() {
        return action;
    }


    public ServicePayload getPayload() {
        return payload;
    }


    public ServiceManager getServices() {
        return services;
    }


    public ServiceRequest getParent() {
        return parent;
    }


    public String getServiceName() {
        return serviceName;
    }


    public EntityRef getPreviousOwner() {
        if ( parent == null ) {
            return null;
        }
        return parent.getOwner();
    }


    public ServiceResults execute() throws Exception {
        try {
            return execute( null );
        }
        catch ( Exception e ) {
            // don't log as error because some exceptions are not actually errors, e.g. resource not found
            if (logger.isDebugEnabled()) {
                logger.debug(debugString(), e);
            }
            throw e;
        }
    }


    private String debugString() {
        StringBuffer sb = new StringBuffer();
        sb.append( "request details:\n  " );
        sb.append( action );
        sb.append( " " );
        sb.append( this );
        sb.append( "\n  payload: " );
        sb.append( payload );
        sb.append( "\n  owner: " );
        sb.append( owner );
        sb.append( "\n  principal: " );
        sb.append( SecurityUtils.getSubject().getPrincipal() );
        return sb.toString();
    }

    public ServiceContext getAppContext() throws Exception {
        Service s = services.getService( serviceName );

        return s.getContext( action,this,null,payload );
    }

    public ServiceResults execute( ServiceResults previousResults ) throws Exception {

        // initServiceName();

        ServiceResults results = null;
        Service s = services.getService( serviceName );
        if ( s != null ) {
            results = s.invoke( action, this, previousResults, payload );
            if ( ( results != null ) && results.hasMoreRequests() ) {

                results = invokeMultiple( results );
            }
        }

        if ( results == null ) {
            results = new ServiceResults( null, this, previousResults, null, Type.GENERIC, null, null, null );
        }

        return results;
    }


    private ServiceResults invokeMultiple( ServiceResults previousResults ) throws Exception {

        List<ServiceRequest> requests = previousResults.getNextRequests();

        if ( returnsTree ) {

            for ( ServiceRequest request : requests ) {

                ServiceResults rs = request.execute( previousResults );
                if ( rs != null ) {
                    previousResults.setChildResults( rs );
                }
            }

            return previousResults;
        }
        else {
            ServiceResults aggregate_results = null;

            for ( ServiceRequest request : requests ) {

                ServiceResults rs = request.execute( previousResults );
                if ( rs != null ) {
                    if ( aggregate_results == null ) {
                        aggregate_results = rs;
                    }
                    else {
                        aggregate_results.merge( rs );
                    }
                }
            }

            return aggregate_results;
        }
    }


    public List<ServiceParameter> getParameters() {
        return parameters;
    }


    public boolean hasParameters() {
        return !isEmpty( parameters );
    }


    public EntityRef getOwner() {
        return owner;
    }


    public Query getLastQuery() {
        if ( !isEmpty( parameters ) ) {
            return last( parameters ).getQuery();
        }
        return null;
    }


    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        if ( serviceName != null ) {
            sb.append( "/" );
            sb.append( serviceName );
        }
        for ( int i = 0; i < parameters.size(); i++ ) {
            ServiceParameter p = parameters.get( i );
            if ( p instanceof QueryParameter ) {
                if ( i == ( parameters.size() - 1 ) ) {
                    sb.append( '?' );
                }
                else {
                    sb.append( ';' );
                }
                boolean has_prev_param = false;
                String q = p.toString();
                if ( isNotBlank( q ) ) {
                    try {
                        sb.append("ql=").append(URLEncoder.encode(q, "UTF-8"));
                    }
                    catch ( UnsupportedEncodingException e ) {
                        logger.error( "Unable to encode url", e );
                    }
                    has_prev_param = true;
                }
                int limit = p.getQuery().getLimit();
                if ( limit != Query.DEFAULT_LIMIT ) {
                    if ( has_prev_param ) {
                        sb.append( '&' );
                    }
                    sb.append("limit=").append(limit);
                    has_prev_param = true;
                }
                if ( p.getQuery().getStartResult() != null ) {
                    if ( has_prev_param ) {
                        sb.append( '&' );
                    }
                    sb.append("start=").append(p.getQuery().getStartResult());
                    has_prev_param = true;
                }
            }
            else {
                sb.append( '/' );
                sb.append( p.toString() );
            }
        }
        return sb.toString();
    }


    public String getChildPath() {
        return childPath;
    }


    public boolean isReturnsTree() { return returnsTree; }

    public boolean isReturnsInboundConnections() { return returnsInboundConnections; }

    public boolean isReturnsOutboundConnections() { return returnsOutboundConnections; }

    public List<ServiceParameter> getOriginalParameters() {
        return originalParameters;
    }

    public boolean isAnalyzeQueryOnly(){
        return analyzeQueryOnly;
    }

    public boolean shouldReturnQuery(){
        return returnQuery;
    }
}
