/*
 * 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 SF 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.hc.support.impl;

import java.util.Arrays;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.ConfigurationPolicy;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyUnbounded;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.engine.SlingRequestProcessor;
import org.apache.sling.hc.api.HealthCheck;
import org.apache.sling.hc.api.Result;
import org.apache.sling.hc.util.FormattingResultLog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** {@link HealthCheck} that checks the HTTP status of Sling requests.
 *  Typically used to check that a freshly installed Sling-based system
 *  is in good shape, contains all required content etc. */
@Component(
        name="org.apache.sling.hc.support.SlingRequestStatusHealthCheck",
        configurationFactory=true,
        policy=ConfigurationPolicy.REQUIRE,
        metatype=true,
        label="Apache Sling Request Status Health Check",
        description="Checks the HTTP status of Sling requests.")
@Properties({
    @Property(name=HealthCheck.NAME,
            label="Health Check Name", description="Name of this Health Check service."),
    @Property(name=HealthCheck.TAGS, unbounded=PropertyUnbounded.ARRAY,
             label="Health Check tags", description="List of tags for this Health Check service, used to select " +
               "subsets of Health Check services for execution"),
    @Property(name=HealthCheck.MBEAN_NAME,
             label="MBean Name", description="Name of the MBean to create for this Health Check.")
})
@Service(value=HealthCheck.class)
public class SlingRequestStatusHealthCheck implements HealthCheck {

    private static final Logger log = LoggerFactory.getLogger(SlingRequestStatusHealthCheck.class);
    private String [] paths;

    static class PathSpec {
        int status;
        String path;

        PathSpec(String configuredPath, FormattingResultLog resultLog) {
            path = configuredPath;
            status = 200;

            final String [] parts  = configuredPath.split(":");
            if(parts.length == 2) {
                try {
                    status = Integer.valueOf(parts[1].trim());
                    path = parts[0].trim();
                } catch(NumberFormatException nfe) {
                    resultLog.healthCheckError("NumberFormatException while parsing [{}], invalid status value?", configuredPath);
                }
            }
        }
    }

    @Property(unbounded=PropertyUnbounded.ARRAY,
            label="Paths to Check",
            description="The list of paths to check, optionally with expected HTTP status responses. " +
                        "An entry like \"/tmp/test.txt:301\", for example, checks that /tmp/test.txt returns a " +
                        "301 response.")
    private static final String PROP_PATH = "path";

    @Reference
    private SlingRequestProcessor requestProcessor;

    @Reference
    private ResourceResolverFactory resolverFactory;

    @Activate
    public void activate(final Map<String, Object> properties) {
        paths = PropertiesUtil.toStringArray(properties.get(PROP_PATH), new String [] {});
        log.info("Activated, paths={}", Arrays.asList(paths));
    }

    @Override
    public Result execute() {
        final FormattingResultLog resultLog = new FormattingResultLog();

        ResourceResolver resolver = null;
        int checked = 0;
        int failed = 0;
        String lastPath = null;

        try {
            resolver = resolverFactory.getAdministrativeResourceResolver(null);
            for(String p : paths) {
                lastPath = p;
                final PathSpec ps = new PathSpec(p, resultLog);
                final HttpServletRequest request = new InternalRequest(ps.path);
                final InternalResponse response = new InternalResponse();
                requestProcessor.processRequest(request, response, resolver);
                final int status = response.getStatus();
                if(status != ps.status) {
                    failed++;
                    resultLog.warn("[{}] returns status {}, expected {}", new Object[] { ps.path, status, ps.status });
                } else {
                    resultLog.debug("[{}] returns status {} as expected", ps.path, status);
                }
                checked++;
            }
        } catch(Exception e) {
            resultLog.warn("Exception while executing request [{}]: {}", lastPath, e);
        } finally {
            if(resolver != null) {
                resolver.close();
            }
        }

        if(checked == 0) {
            resultLog.warn("No paths checked, empty paths list?");
        } else {
            resultLog.info("{} paths checked, {} failures", checked, failed);
        }

        return new Result(resultLog);
    }
}