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


import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Optional;
import org.apache.commons.lang.StringUtils;
import org.apache.usergrid.persistence.index.SelectFieldMapping;
import org.apache.usergrid.persistence.index.exceptions.QueryParseException;
import org.apache.usergrid.persistence.index.query.CounterResolution;
import org.apache.usergrid.persistence.index.query.Identifier;
import org.apache.usergrid.persistence.index.query.tree.Operand;
import org.apache.usergrid.persistence.index.utils.ClassUtils;
import org.apache.usergrid.persistence.index.utils.ListUtils;
import org.apache.usergrid.persistence.index.utils.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
import java.util.Map.Entry;


public class Query {


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

    public enum Level {
        IDS, REFS, CORE_PROPERTIES, ALL_PROPERTIES, LINKED_PROPERTIES
    }

    public static final int DEFAULT_LIMIT = 10;

    public static final int MID_LIMIT = 500;

    public static final int MAX_LIMIT = 1000;

    public static final String PROPERTY_UUID = "uuid";

    private String type;
    private Operand rootOperand;
    private UUID startResult;
    private Optional<String> cursor = Optional.absent();
    private int limit = 0;

    private boolean mergeSelectResults = false;
    private Level level = Level.ALL_PROPERTIES;
    private String connectionType;
    private List<String> permissions;
    private boolean reversed;
    private boolean reversedSet = false;
    private Long startTime;
    private Long finishTime;
    private boolean pad;
    private boolean connecting = false;
    private CounterResolution resolution = CounterResolution.ALL;
    private List<Identifier> identifiers;
    private List<CounterFilterPredicate> counterFilters;
    private String collection;
    private String ql;
    private Collection<SelectFieldMapping> selectFields;
    private boolean analyzeOnly = false;
    private boolean returnQuery = false;


    private static ObjectMapper mapper = new ObjectMapper();


    List<Operand> filterClauses = new ArrayList<Operand>();

    public Query() {
    }


    /**
     * Creates a deep copy of a query from another query
     * @param q
     */
    public Query( Query q ) {
        if ( q == null ) {
            return;
        }

        ql = q.ql;
        type = q.type;
        startResult = q.startResult;
        cursor = q.cursor;
        limit = q.limit;
        mergeSelectResults = q.mergeSelectResults;
        //level = q.level;
        connectionType = q.connectionType;
        permissions = q.permissions != null ? new ArrayList<>( q.permissions ) : null;
        reversed = q.reversed;
        reversedSet = q.reversedSet;
        startTime = q.startTime;
        finishTime = q.finishTime;
        resolution = q.resolution;
        pad = q.pad;
        rootOperand = q.rootOperand;
        identifiers = q.identifiers != null
                ? new ArrayList<>( q.identifiers ) : null;
        counterFilters = q.counterFilters != null
                ? new ArrayList<>( q.counterFilters ) : null;
        collection = q.collection;
        level = q.level;
        analyzeOnly = q.analyzeOnly;
        returnQuery = q.returnQuery;
    }



    /**
     * Create a query instance from the QL.  If the string is null, return an empty query
     * @param ql
     * @return
     */
    public static Query fromQLNullSafe(final String ql){
        final Query query = fromQL(ql);

        if(query != null){
            return query;
        }

        return new Query();
    }

    public static Query fromQL( String ql ) throws QueryParseException {
        if ( StringUtils.isEmpty(ql) ) {
            return null;
        }

        Query query = new Query(  );
        query.setQl( ql );

        return query;
    }
    public static Query all( ){
        return fromQL("select *");
    }

    /**
     * Create a query from a property equals
     * @param propertyName
     * @param value
     * @return
     */
    public static Query fromEquals(final String propertyName, final String value){
        return fromQL( propertyName + " = '" + value + "'" );
    }


    private static Query newQueryIfNull( Query query ) {
        if ( query == null ) {
            query = new Query();
        }
        return query;
    }


    public static Query fromJsonString( String json ) throws QueryParseException {

        Object o;
        try {
            o = mapper.readValue( json, Object.class );
        } catch (IOException ex) {
            throw new QueryParseException("Error parsing JSON query string " + json, ex);
        }

        if ( o instanceof Map ) {
            @SuppressWarnings({ "unchecked", "rawtypes" }) Map<String, List<String>> params =
                    ClassUtils.cast( MapUtils.toMapList( ( Map ) o ) );
            return fromQueryParams( params );
        }
        return null;
    }


    public static Query fromQueryParams( Map<String, List<String>> params )
            throws QueryParseException {
        Query q = null;
        CounterResolution resolution = null;
        List<Identifier> identifiers = null;
        List<CounterFilterPredicate> counterFilters = null;

        String ql = QueryUtils.queryStrFrom( params );
        String type = ListUtils.first( params.get( "type" ) );
        Boolean reversed = ListUtils.firstBoolean( params.get( "reversed" ) );
        String connection = ListUtils.first( params.get( "connectionType" ) );
        UUID start = ListUtils.firstUuid( params.get( "start" ) );
        String cursor = ListUtils.first( params.get( "cursor" ) );
        Integer limit = ListUtils.firstInteger( params.get( "limit" ) );
        List<String> permissions = params.get( "permission" );
        Long startTime = ListUtils.firstLong( params.get( "start_time" ) );
        Long finishTime = ListUtils.firstLong( params.get( "end_time" ) );

        List<String> l = params.get( "resolution" );
        if ( !ListUtils.isEmpty( l ) ) {
            resolution = CounterResolution.fromString( l.get( 0 ) );
        }

        l = params.get( "counter" );

        if ( !ListUtils.isEmpty( l ) ) {
            counterFilters = CounterFilterPredicate.fromList( l );
        }

        Boolean pad = ListUtils.firstBoolean( params.get( "pad" ) );

        for ( Entry<String, List<String>> param : params.entrySet() ) {
            Identifier identifier = Identifier.from( param.getKey() );
            if ( ( param.getValue() == null ) || ( param.getValue().size() == 0 ) || identifier.isUUID() ) {
                if ( identifier != null ) {
                    if ( identifiers == null ) {
                        identifiers = new ArrayList<Identifier>();
                    }
                    identifiers.add( identifier );
                }
            }
        }

        if ( ql != null ) {
            ql = ql.replace("+", "%2b"); // ql string supports literal + symbol, encode so it will decode correctly later
            q = Query.fromQL( decode( ql ) );
        }


        if ( type != null ) {
            q = newQueryIfNull( q );
            q.setEntityType( type );
        }

        if ( connection != null ) {
            q = newQueryIfNull( q );
            q.setConnectionType( connection );
        }

        if ( permissions != null ) {
            q = newQueryIfNull( q );
            q.setPermissions( permissions );
        }

        if ( start != null ) {
            q = newQueryIfNull( q );
            q.setStartResult( start );
        }

        if ( cursor != null ) {
            q = newQueryIfNull( q );
            q.setCursor( cursor );
        }

        if ( limit != null ) {
            q = newQueryIfNull( q );
            q.setLimit( limit );
        }

        if ( startTime != null ) {
            q = newQueryIfNull( q );
            q.setStartTime( startTime );
        }

        if ( finishTime != null ) {
            q = newQueryIfNull( q );
            q.setFinishTime( finishTime );
        }

        if ( resolution != null ) {
            q = newQueryIfNull( q );
            q.setResolution( resolution );
        }

        if ( counterFilters != null ) {
            q = newQueryIfNull( q );
            q.setCounterFilters( counterFilters );
        }

        if ( pad != null ) {
            q = newQueryIfNull( q );
            q.setPad( pad );
        }

        if ( identifiers != null ) {
            q = newQueryIfNull( q );
            q.setIdentifiers( identifiers );
        }

        if ( reversed != null ) {
            q = newQueryIfNull( q );
            q.setReversed( reversed );
        }

        return q;
    }


    public static Query fromUUID( UUID uuid ) {
        Query q = new Query();
        q.addIdentifier( Identifier.fromUUID( uuid ) );
        return q;
    }


    public static Query fromIdentifier( Object id ) {
        if (id == null) {
            throw new IllegalArgumentException("null identifier passed in");
        }
        Identifier objectIdentifier = Identifier.from(id);
        if (objectIdentifier == null) {
            throw new IllegalArgumentException("Supplied id results in null Identifier");
        }
        Query q = new Query();
        q.addIdentifier( Identifier.from(id) );
        return q;
    }


    public boolean hasQueryPredicates() {
        return rootOperand != null;
    }


    /**
     * Return true if the query generated select subjects
     * @return
     */
    public boolean hasSelectSubjects() {
        if ( this.selectFields != null )
            if ( this.selectFields.size()>0 )
                return true;

        return false;
    }


    /**
     * Set the select subjects from our query results
     */
    public void setSelectSubjects( final Collection<SelectFieldMapping> selectFields ) {
        this.selectFields = selectFields;
    }


    /**
     * Get the select assignments from our resetus if they were set
     */
    public Collection<SelectFieldMapping> getSelectAssignments() {
        return this.selectFields;
    }


    public boolean containsNameOrEmailIdentifiersOnly() {
        if ( hasQueryPredicates() ) {
            return false;
        }
        if ( ( identifiers == null ) || identifiers.isEmpty() ) {
            return false;
        }
        for ( Identifier identifier : identifiers ) {
            if ( !identifier.isEmail() && !identifier.isName() ) {
                return false;
            }
        }
        return true;
    }


    @JsonIgnore
    public String getSingleNameOrEmailIdentifier() {
        if ( !containsSingleNameOrEmailIdentifier() ) {
            return null;
        }
        return ( identifiers.get( 0 ).toString() );
    }


    public boolean containsSingleNameOrEmailIdentifier() {
        return containsNameOrEmailIdentifiersOnly() && ( identifiers.size() == 1 );
    }


    @JsonIgnore
    public Identifier getSingleIdentifier() {
        return identifiers != null && identifiers.size() == 1 ? identifiers.get( 0 ) : null;
    }


    public boolean containsSingleUuidIdentifier() {
        return containsUuidIdentifiersOnly() && ( identifiers.size() == 1 );
    }


    boolean containsUuidIdentifiersOnly() {
        if ( hasQueryPredicates() ) {
            return false;
        }
        if ( ( identifiers == null ) || identifiers.isEmpty() ) {
            return false;
        }

        for ( Identifier identifier : identifiers ) {
            if (identifier == null) {
                logger.error("containsUuidIdentifiersOnly(): identifier in identifiers list is null");
                return false;
            }
            if ( !identifier.isUUID() ) {
                return false;
            }
        }
        return true;
    }


    @JsonIgnore
    public UUID getSingleUuidIdentifier() {
        if ( !containsSingleUuidIdentifier() ) {
            return null;
        }
        return ( identifiers.get( 0 ).getUUID() );
    }


    @JsonIgnore
    boolean isIdsOnly() {
        return false;
    }

    private void setIdsOnly( boolean idsOnly ) {
        if ( idsOnly ) {
            level = Level.IDS;
        }
        else if ( isIdsOnly() ) {
            level = Level.ALL_PROPERTIES;
        }
    }


    public Level getResultsLevel() {
        isIdsOnly();
        return level;
    }


    public void setResultsLevel( Level level ) {
        setIdsOnly( level == Level.IDS );
        this.level = level;
    }


    public Query withResultsLevel( Level level ) {
        setIdsOnly( level == Level.IDS );
        this.level = level;
        return this;
    }


    public Query withReversed( boolean reversed ) {
        setReversed( reversed );
        return this;
    }


    public String getEntityType() {
        return type;
    }


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

    public List<String> getPermissions() {
        return permissions;
    }


    public void setPermissions( List<String> permissions ) {
        this.permissions = permissions;
    }

    public void setAnalyzeOnly(final boolean analyzeOnly){
        this.analyzeOnly = analyzeOnly;
    }

    public boolean getAnalyzeOnly(){
        return analyzeOnly;
    }

    public void setReturnQuery(final boolean returnQuery) {
        this.returnQuery = returnQuery;
    }

    public boolean getReturnQuery() {
        return returnQuery;
    }

    public boolean isMergeSelectResults() {
        return mergeSelectResults;
    }



    void setStartResult( UUID startResult ) {
        this.startResult = startResult;
    }


    public Query withStartResult( UUID startResult ) {
        this.startResult = startResult;
        return this;
    }


    public UUID getStartResult() {
        return startResult;
    }


    public Optional<String> getCursor() {
        return cursor;
    }


    public void setCursor( String cursor ) {
        this.cursor = Optional.fromNullable( cursor );
    }


    public Query withCursor( String cursor ) {
        setCursor( cursor );
        return this;
    }


    public int getLimit() {
        return getLimit( DEFAULT_LIMIT );
    }


    public int getLimit( int defaultLimit ) {
        if ( limit <= 0 ) {
            return  defaultLimit > 0 ? defaultLimit : DEFAULT_LIMIT;
        }
        return limit;
    }


    public void setLimit( int limit ) {

        // TODO tnine.  After users have had time to change their query limits,
        // this needs to be uncommented and enforced.
        //    if(limit > MAX_LIMIT){
        //        throw new IllegalArgumentException(
        //            String.format("Query limit must be <= to %d", MAX_LIMIT));
        //    }

        if ( limit > MAX_LIMIT ) {
            limit = MAX_LIMIT;
        }

        this.limit = limit;
    }


    public Query withLimit( int limit ) {
        setLimit( limit );
        return this;
    }


    public boolean isReversed() {
        return reversed;
    }


    public void setReversed( boolean reversed ) {
        reversedSet = true;
        this.reversed = reversed;
    }


    public boolean isReversedSet() {
        return reversedSet;
    }


    public Long getStartTime() {
        return startTime;
    }


    public void setStartTime( Long startTime ) {
        this.startTime = startTime;
    }


    public Long getFinishTime() {
        return finishTime;
    }


    public void setFinishTime( Long finishTime ) {
        this.finishTime = finishTime;
    }


    public boolean isPad() {
        return pad;
    }


    public void setPad( boolean pad ) {
        this.pad = pad;
    }

    //set the flag to retrieve the edges in the reverse direction.
    public void setConnecting( boolean connecting ) {
        this.connecting = connecting;
    }

    public boolean isConnecting() {
        return connecting;
    }


    public void setResolution( CounterResolution resolution ) {
        this.resolution = resolution;
    }


    public CounterResolution getResolution() {
        return resolution;
    }


    public void addIdentifier( Identifier identifier ) {
        if ( identifiers == null ) {
            identifiers = new ArrayList<Identifier>();
        }
        if (identifier == null) {
            throw new IllegalArgumentException("adding null identifier is not allowed");
        }
        identifiers.add( identifier );
    }


    void setIdentifiers( List<Identifier> identifiers ) {
        this.identifiers = identifiers;
    }


    public List<CounterFilterPredicate> getCounterFilters() {
        return counterFilters;
    }


    public void addCounterFilter( String counter ) {
        CounterFilterPredicate p = CounterFilterPredicate.fromString( counter );
        if ( p == null ) {
            return;
        }
        if ( counterFilters == null ) {
            counterFilters = new ArrayList<CounterFilterPredicate>();
        }
        counterFilters.add( p );
    }


    void setCounterFilters( List<CounterFilterPredicate> counterFilters ) {
        this.counterFilters = counterFilters;
    }



    public static final class CounterFilterPredicate implements Serializable {

        private static final long serialVersionUID = 1L;
        private final String name;
        private final Identifier user;
        private final Identifier group;
        private final String queue;
        private final String category;


        public CounterFilterPredicate( String name, Identifier user, Identifier group, String queue, String category ) {
            this.name = name;
            this.user = user;
            this.group = group;
            this.queue = queue;
            this.category = category;
        }


        public Identifier getUser() {
            return user;
        }


        public Identifier getGroup() {
            return group;
        }


        public String getQueue() {
            return queue;
        }


        public String getCategory() {
            return category;
        }


        public String getName() {
            return name;
        }


        public static CounterFilterPredicate fromString( String s ) {
            Identifier user = null;
            Identifier group = null;
            String category = null;
            String name = null;
            String[] l = StringUtils.split( s, ':' );

            if ( l.length > 0 ) {
                if ( !"*".equals( l[0] ) ) {
                    name = l[0];
                }
            }

            if ( l.length > 1 ) {
                if ( !"*".equals( l[1] ) ) {
                    user = Identifier.from( l[1] );
                }
            }

            if ( l.length > 2 ) {
                if ( !"*".equals( l[2] ) ) {
                    group = Identifier.from( l[3] );
                }
            }

            if ( l.length > 3 ) {
                if ( !"*".equals( l[3] ) ) {
                    category = l[3];
                }
            }

            if ( ( user == null ) && ( group == null ) && ( category == null ) && ( name == null)) {
                return null;
            }

            return new CounterFilterPredicate( name, user, group, null, category );
        }


        public static List<CounterFilterPredicate> fromList( List<String> l ) {
            if ( ( l == null ) || ( l.size() == 0 ) ) {
                return null;
            }
            List<CounterFilterPredicate> counterFilters = new ArrayList<CounterFilterPredicate>();
            for ( String s : l ) {
                CounterFilterPredicate filter = CounterFilterPredicate.fromString( s );
                if ( filter != null ) {
                    counterFilters.add( filter );
                }
            }
            if ( counterFilters.size() == 0 ) {
                return null;
            }
            return counterFilters;
        }
    }


//    public List<Object> getSelectionResults( Results rs ) {
//
//        List<Entity> entities = rs.getEntities();
//        if ( entities == null ) {
//            return null;
//        }
//
//        if ( !hasSelectSubjects() ) {
//            return cast( entities );
//        }
//
//        List<Object> results = new ArrayList<Object>();
//
//        for ( Entity entity : entities ) {
//            if ( isMergeSelectResults() ) {
//                boolean include = false;
//                Map<String, Object> result = new LinkedHashMap<String, Object>();
//                Map<String, String> selects = getSelectAssignments();
//                for ( Map.Entry<String, String> select : selects.entrySet() ) {
//                    Object obj = JsonUtils.select( entity, select.getValue(), false );
//                    if ( obj != null ) {
//                        include = true;
//                    }
//                    result.put( select.getKey(), obj );
//                }
//                if ( include ) {
//                    results.add( result );
//                }
//            }
//            else {
//                boolean include = false;
//                List<Object> result = new ArrayList<Object>();
//                Set<String> selects = getSelectSubjects();
//                for ( String select : selects ) {
//                    Object obj = JsonUtils.select( entity, select );
//                    if ( obj != null ) {
//                        include = true;
//                    }
//                    result.add( obj );
//                }
//                if ( include ) {
//                    results.add( result );
//                }
//            }
//        }
//
//        if ( results.size() == 0 ) {
//            return null;
//        }
//
//        return results;
//    }


//    public Object getSelectionResult( Results rs ) {
//        List<Object> r = getSelectionResults( rs );
//        if ( ( r != null ) && ( r.size() > 0 ) ) {
//            return r.get( 0 );
//        }
//        return null;
//    }


    private static String decode( String input ) {
        try {
            return URLDecoder.decode( input, "UTF-8" );
        }
        catch ( UnsupportedEncodingException e ) {
            // shouldn't happen, but just in case
            throw new RuntimeException( e );
        }
    }


    // note: very likely to be null
    public String getCollection() {
        return collection;
    }


    public void setCollection( String collection ) {
        this.collection = collection;
    }


    // may be null
    public Optional<String> getQl() {

        //if a query exists, but with no ql, we select all
       return Optional.fromNullable( ql );
    }


    /**
     * Return true if no query is present and we should perform a graph search
     * @return
     */
    @JsonIgnore
    public boolean isGraphSearch(){
        return ql == null || ql.trim().toLowerCase().equals("select *");
    }


    public Query setQl( String ql ) {
        this.ql = ql;
        return this;
    }


    /**
     * Get the connection type
     * @return
     */
    public String getConnectionType() {
        return connectionType;
    }


    /**
     * Set the connection type
     * @param connection
     * @return
     */
    public Query setConnectionType( final String connection ) {
        this.connectionType = connection;
        return this;
    }


    public String getType() {
        return type;
    }


    public Level getLevel() {
        return level;
    }
}
