/*
 * 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.cms.core.models;

import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.inject.Inject;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.osgi.annotation.versioning.ProviderType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ProviderType
@Model(adaptables = SlingHttpServletRequest.class)
public class QueryDebugger {

    private static final String MBEAN_NAME = "org.apache.jackrabbit.oak:name=Oak Query Statistics (Extended),type=QueryStats";

    private static final Logger log = LoggerFactory.getLogger(QueryDebugger.class);
    private final String plan;
    private final long duration;
    private final long estimatedSize;
    private final String exception;
    private final List<Resource> results = new ArrayList<>();
    private final String statement;
    private final List<Map<String, Object>> slowQueries = new ArrayList<>();
    private final List<Map<String, Object>> popularQueries = new ArrayList<>();
    private final boolean enabled;

    @Inject
    public QueryDebugger(@Self SlingHttpServletRequest request) {

        Optional<String> statementParam = Optional.ofNullable(request.getParameter("statement"));
        String language = Optional.ofNullable(request.getParameter("language")).orElse(Query.JCR_SQL2);

        int limit = Optional.ofNullable(request.getParameter("sample")).map(s -> Integer.parseInt(s, 10)).orElse(0);

        boolean lenabled = false;
        long lestimate = 0;
        long lduration = -1;
        String lplan = null;
        String lexception = null;
        String lstatement = null;
        try {
            if (statementParam.isPresent()) {

                QueryManager queryManager = request.getResourceResolver().adaptTo(Session.class).getWorkspace()
                        .getQueryManager();
                Query explainQuery = queryManager.createQuery("explain measure " + statementParam.get(), language);
                Row row = explainQuery.execute().getRows().nextRow();
                lplan = row.getValue("plan").getString();
                lstatement = statementParam.get();

                if (limit > 0) {
                    lenabled = true;
                    long start = System.currentTimeMillis();
                    Query query = queryManager.createQuery(statementParam.get(), language);
                    query.setLimit(limit);
                    QueryResult queryResult = query.execute();
                    RowIterator rowIterator = queryResult.getRows();
                    lestimate = rowIterator.getSize();
                    lduration = System.currentTimeMillis() - start;
                    while (rowIterator.hasNext()) {
                        Optional.ofNullable(rowIterator.nextRow())
                                .map(n -> {
                                    try {
                                        return request.getResourceResolver().getResource(n.getPath());
                                    } catch (RepositoryException e) {
                                        log.warn("Exception getting path from row: {}", n, e);
                                        return null;
                                    }
                                })
                                .ifPresent(results::add);
                    }
                }
            }
        } catch (RepositoryException re) {
            lexception = re.toString();
            log.warn("Failed to debug query: {}", statementParam, re);
        } finally {
            this.plan = lplan;
            this.duration = lduration;
            this.exception = lexception;
            this.statement = lstatement;
            this.estimatedSize = lestimate;
            this.enabled = lenabled;
        }

        try {
            collectMbeanData("PopularQueries", popularQueries);
            collectMbeanData("SlowQueries", slowQueries);
        } catch (MBeanException | MalformedObjectNameException | InstanceNotFoundException | AttributeNotFoundException
                | NullPointerException | ReflectionException e) {
            log.warn("Failed to load mBean data", e);
        }
    }

    private void collectMbeanData(String attributeName, List<Map<String, Object>> target)
            throws MalformedObjectNameException, NullPointerException, InstanceNotFoundException,
            AttributeNotFoundException, ReflectionException, MBeanException {
        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        ObjectName mbeanName = ObjectName.getInstance(MBEAN_NAME);
        TabularData data = (TabularData) mBeanServer.getAttribute(mbeanName, attributeName);
        data.values().stream().map(CompositeData.class::cast)
                .forEach(compositeData -> target.add(compositeData.getCompositeType().keySet().stream()
                        .collect(Collectors.toMap(k -> k, compositeData::get))));
    }

    /**
     * @return the execution duration or -1
     */
    public long getDuration() {
        return duration;
    }

    /**
     * @return the estimated size
     */
    public long getEstimatedSize() {
        return estimatedSize;
    }

    /**
     * @return if execution enabled
     */
    public boolean isExecutionEnabled() {
        return enabled;
    }

    /**
     * @return the exception
     */
    public String getException() {
        return exception;
    }

    /**
     * @return the plan
     */
    public String getPlan() {
        return plan;
    }

    /**
     * @return the results
     */
    public List<Resource> getResults() {
        return results;
    }

    /**
     * @return the statement
     */
    public String getStatement() {
        return statement;
    }

    /**
     * @return the slowQueries
     */
    public List<Map<String, Object>> getSlowQueries() {
        return slowQueries;
    }

    /**
     * @return the popularQueries
     */
    public List<Map<String, Object>> getPopularQueries() {
        return popularQueries;
    }

}
