/*
 * 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.sling.jcr.resource.internal.helper.jcr;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;

import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;

import org.apache.commons.lang.ArrayUtils;
import org.apache.sling.api.SlingException;
import org.apache.sling.api.resource.QuerySyntaxException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.wrappers.ValueMapDecorator;
import org.apache.sling.jcr.resource.internal.helper.JcrResourceUtil;
import org.apache.sling.spi.resource.provider.QueryLanguageProvider;
import org.apache.sling.spi.resource.provider.ProviderContext;
import org.apache.sling.spi.resource.provider.ResolveContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BasicQueryLanguageProvider implements QueryLanguageProvider<JcrProviderState> {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @SuppressWarnings("deprecation")
    private static final String DEFAULT_QUERY_LANGUAGE = Query.XPATH;

    /** column name for node path */
    private static final String QUERY_COLUMN_PATH = "jcr:path";

    /** column name for score value */
    private static final String QUERY_COLUMN_SCORE = "jcr:score";

    /** The provider context. */
    private final ProviderContext providerContext;

    public BasicQueryLanguageProvider(final ProviderContext ctx) {
        this.providerContext = ctx;
    }

    @Override
    public String[] getSupportedLanguages(final ResolveContext<JcrProviderState> ctx) {
        try {
            return ctx.getProviderState().getSession().getWorkspace().getQueryManager().getSupportedQueryLanguages();
        } catch (final RepositoryException e) {
            throw new SlingException("Unable to discover supported query languages", e);
        }
    }

    @Override
    public Iterator<Resource> findResources(final ResolveContext<JcrProviderState> ctx,
            final String query,
            final String language) {
        try {
            final QueryResult res = JcrResourceUtil.query(ctx.getProviderState().getSession(), query, language);
            return new JcrNodeResourceIterator(ctx.getResourceResolver(),
                    null, null,
                    res.getNodes(),
                    ctx.getProviderState().getHelperData(),
                    this.providerContext.getExcludedPaths());
        } catch (final javax.jcr.query.InvalidQueryException iqe) {
            throw new QuerySyntaxException(iqe.getMessage(), query, language, iqe);
        } catch (final RepositoryException re) {
            throw new SlingException(re.getMessage(), re);
        }
    }

    @Override
    public Iterator<ValueMap> queryResources(final ResolveContext<JcrProviderState> ctx,
            final String query,
            final String language) {
        final String queryLanguage = ArrayUtils.contains(getSupportedLanguages(ctx), language) ? language : DEFAULT_QUERY_LANGUAGE;

        try {
            final QueryResult result = JcrResourceUtil.query(ctx.getProviderState().getSession(), query, queryLanguage);
            final String[] colNames = result.getColumnNames();
            final RowIterator rows = result.getRows();

            return new Iterator<ValueMap>() {

                private ValueMap next;

                {
                    next = seek();
                }

                @Override
                public boolean hasNext() {
                    return next != null;
                };

                @Override
                public ValueMap next() {
                    if ( next == null ) {
                        throw new NoSuchElementException();
                    }
                    final ValueMap result = next;
                    next = seek();
                    return result;
                }

                private ValueMap seek() {
                    ValueMap result = null;
                    while ( result == null && rows.hasNext() ) {
                        try {
                            final Row jcrRow = rows.nextRow();
                            final String resourcePath = jcrRow.getPath();
                            if ( resourcePath != null && providerContext.getExcludedPaths().matches(resourcePath) == null) {
                                final Map<String, Object> row = new HashMap<String, Object>();

                                boolean didPath = false;
                                boolean didScore = false;
                                final Value[] values = jcrRow.getValues();
                                for (int i = 0; i < values.length; i++) {
                                    Value v = values[i];
                                    if (v != null) {
                                        String colName = colNames[i];
                                        row.put(colName,
                                            JcrResourceUtil.toJavaObject(values[i]));
                                        if (colName.equals(QUERY_COLUMN_PATH)) {
                                            didPath = true;
                                            row.put(colName, JcrResourceUtil.toJavaObject(values[i]).toString());
                                        }
                                        if (colName.equals(QUERY_COLUMN_SCORE)) {
                                            didScore = true;
                                        }
                                    }
                                }
                                if (!didPath) {
                                    row.put(QUERY_COLUMN_PATH, jcrRow.getPath());
                                }
                                if (!didScore) {
                                    row.put(QUERY_COLUMN_SCORE, jcrRow.getScore());
                                }
                                result = new ValueMapDecorator(row);
                            }
                        } catch (final RepositoryException re) {
                            logger.error(
                                "queryResources$next: Problem accessing row values",
                                re);
                        }
                    }
                    return result;
                }

                @Override
                public void remove() {
                    throw new UnsupportedOperationException("remove");
                }
            };
        } catch (final javax.jcr.query.InvalidQueryException iqe) {
            throw new QuerySyntaxException(iqe.getMessage(), query, language,
                iqe);
        } catch (final RepositoryException re) {
            throw new SlingException(re.getMessage(), re);
        }

    }

}
