/*
 * 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.jena.sparql.core ;

import java.util.Objects;

import org.apache.jena.atlas.lib.Lib ;
import org.apache.jena.query.Query ;
import org.apache.jena.query.QueryVisitor ;
import org.apache.jena.sparql.util.NodeIsomorphismMap ;

// Two queries comparison 

public class QueryCompare implements QueryVisitor
{
    private Query   query2 ;
    private boolean result = true ;
    static public boolean PrintMessages = false ;

    public static boolean equals(Query query1, Query query2)
    {
        if ( query1 == query2 ) return true ;
        
        query1.setResultVars() ;
        query2.setResultVars() ;
        QueryCompare visitor = new QueryCompare(query1) ;
        try {
            query2.visit(visitor) ;
        } catch ( ComparisonException ex)
        {
            return false ;
        }
        return visitor.isTheSame() ;
    }
    
    public QueryCompare(Query query2)
    {
        this.query2 = query2 ;
        
    }

    @Override
    public void startVisit(Query query1)
    {  }  

    @Override
    public void visitResultForm(Query query1)
    { check("Query result form", query1.getQueryType() == query2.getQueryType()) ; }

    @Override
    public void visitPrologue(Prologue query1)
    {
        check("Prefixes/Base", query1.samePrologue(query2) ) ;
    }

    @Override
    public void visitSelectResultForm(Query query1)
    { 
        check("Not both SELECT queries", query2.isSelectType()) ;
        check("DISTINCT modifier",
              query1.isDistinct() == query2.isDistinct()) ;
        check("SELECT *", query1.isQueryResultStar() == query2.isQueryResultStar()) ;
        check("Result variables",   query1.getProject(), query2.getProject() ) ;
    }

    @Override
    public void visitConstructResultForm(Query query1)
    {
        check("Not both CONSTRUCT queries", query2.isConstructType()) ;
        check("CONSTRUCT templates", 
              query1.getConstructTemplate().equalIso(query2.getConstructTemplate(), new NodeIsomorphismMap()) ) ;
    }

    @Override
    public void visitDescribeResultForm(Query query1)
    {
        check("Not both DESCRIBE queries", query2.isDescribeType()) ;
        check("Result variables", 
              query1.getResultVars(), query2.getResultVars() ) ;
        check("Result URIs", 
              query1.getResultURIs(), query2.getResultURIs() ) ;
        
    }

    @Override
    public void visitAskResultForm(Query query1)
    {
        check("Not both ASK queries", query2.isAskType()) ;
    }

    @Override
    public void visitJsonResultForm(Query query) {
        check("Not both JSON queries", query2.isJsonType()) ;
    }

    @Override
    public void visitDatasetDecl(Query query1)
    {
        boolean b1 = Lib.equalsListAsSet(query1.getGraphURIs(), query2.getGraphURIs()) ;
        check("Default graph URIs", b1 ) ;
        boolean b2 = Lib.equalsListAsSet(query1.getNamedGraphURIs(), query2.getNamedGraphURIs()) ; 
        check("Named graph URIs", b2 ) ;
    }

    @Override
    public void visitQueryPattern(Query query1)
    {
        if ( query1.getQueryPattern() == null &&
             query2.getQueryPattern() == null )
            return ;
        
        if ( query1.getQueryPattern() == null ) throw new ComparisonException("Missing pattern") ;
        if ( query2.getQueryPattern() == null ) throw new ComparisonException("Missing pattern") ;
        
        // The checking for patterns (elements) involves a potential
        // remapping of system-allocated variable names.
        // Assumes blank node variables only appear in patterns.
        check("Pattern", query1.getQueryPattern().equalTo(query2.getQueryPattern(), new NodeIsomorphismMap())) ;
    }

    @Override
    public void visitGroupBy(Query query1)
    {
        check("GROUP BY", query1.getGroupBy(), query2.getGroupBy()) ;
    }
    
    @Override
    public void visitHaving(Query query1) 
    {
        check("HAVING", query1.getHavingExprs(), query2.getHavingExprs()) ;
    }
    
    @Override
    public void visitLimit(Query query1)
    {
        check("LIMIT", query1.getLimit() == query2.getLimit() ) ;
    }

     @Override
    public void visitOrderBy(Query query1)
     {
         check("ORDER BY", query1.getOrderBy(), query2.getOrderBy() ) ;
     }

     @Override
    public void visitOffset(Query query1)
    {
        check("OFFSET", query1.getOffset() == query2.getOffset() ) ;
    }

    @Override
    public void visitValues(Query query1)
    {
        // Must be same order for now.
        check("VALUES/variables", query1.getValuesVariables(), query2.getValuesVariables()) ;
        check("VALUES/values", query1.getValuesData(), query2.getValuesData()) ;
    }

    @Override
    public void finishVisit(Query query1)
    {}
    
    private void check(String msg, Object obj1, Object obj2)
    {
        check(msg, Objects.equals(obj1,obj2)) ;
    }
    
    private void check(String msg, boolean b)
    {
        if ( !b )
        {
            if ( PrintMessages && msg != null )
                System.out.println("Different: "+msg) ;
            result = false ;
            throw new ComparisonException(msg) ;
        }
    }

    public boolean isTheSame() { return result ; }
}
