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

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.sling.hc.api.HealthCheck;
import org.apache.sling.hc.api.Result;
import org.apache.sling.hc.util.FormattingResultLog;
import org.apache.sling.installer.api.InstallableResource;
import org.apache.sling.installer.api.info.InfoProvider;
import org.apache.sling.installer.api.info.InstallationState;
import org.apache.sling.installer.api.info.Resource;
import org.apache.sling.installer.api.info.ResourceGroup;
import org.apache.sling.installer.hc.OsgiInstallerHealthCheck.Configuration;
import org.osgi.framework.Version;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(property={ HealthCheck.NAME+"="+OsgiInstallerHealthCheck.HC_NAME })
@Designate(ocd=Configuration.class)
public class OsgiInstallerHealthCheck implements HealthCheck {
    protected static final String HC_NAME = "OSGi Installer Health Check";

    @Reference
    private InfoProvider infoProvider;

    private static final Logger LOG = LoggerFactory.getLogger(OsgiInstallerHealthCheck.class);

    private Configuration configuration;
    private Map<String, Version> skipEntityIdsWithVersions;
    
    private final static String DOCUMENTATION_URL = "https://sling.apache.org/documentation/bundles/osgi-installer.html#health-check";

    @Reference
    private ConfigurationAdmin configurationAdmin;
    
    @ObjectClassDefinition(name = HC_NAME, 
            description="Checks that all OSGi configurations/bundles are successfully installed by the OSGi Installer (and are not skipped for some reason).")
    protected static @interface Configuration {
        @AttributeDefinition(name="Tags", description="Tags with which this healthcheck is associated")
        String[] hc_tags() default {"installer", "osgi"};
        
        @AttributeDefinition(name="URL Prefixes to consider", description = "Only those OSGi configurations/bundles whose location are starting with one of the given URL prefixes are checked (whether they are installed correctly). Open /system/console/osgi-installer for a list of valid prefixes.")
        String[] urlPrefixes() default "jcrinstall:/apps/";
        
        @AttributeDefinition(name="Check Bundles", description = "If enabled bundles are checked (restricted to the ones matching one of the prefixes)")
        boolean checkBundles() default true;
        
        @AttributeDefinition(name="Check Configurations", description = "If enabled configurations are checked (restricted to the ones matching one of the prefixes)")
        boolean checkConfigurations() default true;
        
        @AttributeDefinition(name="Allow ignored artifacts in a group", description = "If true there is no warning reported for not installed artifacts if at least one artifact in the same group (i.e. with the same entity id) is installed matching one of the configured URL prefixes. Otherwise there is a warning for every ignored artifact.")
        boolean allowIgnoredArtifactsInGroup() default false;
        
        @AttributeDefinition(name="Skip entity ids", description = "The given entity ids should be skipped for the health check. Each entry has the format '<entity id> [<version>]'.")
        String[] skipEntityIds();
    }

    @Activate
    protected void activate(Configuration configuration) {
        this.configuration = configuration;
        skipEntityIdsWithVersions = parseEntityIdsWithVersions(configuration.skipEntityIds());
    }

    private Map<String, Version> parseEntityIdsWithVersions(String[] entityIdsAndVersions) throws IllegalArgumentException {
        Map<String, Version> entityIdsWithVersions = new HashMap<>();
        if (entityIdsAndVersions != null) {
            for (String entityIdAndVersion : entityIdsAndVersions) {
                String[] parts = entityIdAndVersion.split(" ", 2);
                final String entityId = parts[0];
                final Version version;
                if (parts.length > 1) {
                    version = Version.parseVersion(parts[1]);
                } else {
                    version = null;
                }
                entityIdsWithVersions.put(entityId, version);
            }
        }
        return entityIdsWithVersions;
    }

    @Override
    public Result execute() {
        InstallationState installationState = infoProvider.getInstallationState();
        FormattingResultLog hcLog = new FormattingResultLog();

        int numCheckedConfigurationGroups = 0;
        int numCheckedBundleGroups = 0;
        // go through all resource groups of the OSGi Installer
        for (final ResourceGroup group : installationState.getInstalledResources()) {
            String type = evaluateGroup(group, hcLog);
            switch (type) {
            case InstallableResource.TYPE_CONFIG:
                numCheckedConfigurationGroups++;
                break;
            case InstallableResource.TYPE_BUNDLE:
                numCheckedBundleGroups++;
                break;
            }
        }
        hcLog.info("Checked {} OSGi bundle and {} configuration groups.", numCheckedBundleGroups, numCheckedConfigurationGroups);
        if (hcLog.getAggregateStatus().ordinal() >= Result.Status.WARN.ordinal()) {
            hcLog.info("Refer to the OSGi installer's documentation page at {} for further details on how to fix those issues.", DOCUMENTATION_URL);
        }
        return new Result(hcLog);
    }

    /**
     * @param group
     *            the resource group to evaluate
     * @param hcLog
     *            the log to fill during the health check
     * @return the type of resources in this group ("bundle" or "config") or empty string, if the group was not
     *         considered by this health check
     */
    private String evaluateGroup(ResourceGroup group, FormattingResultLog hcLog) {
        Resource invalidResource = null;
        String resourceType = "";
        boolean isGroupRelevant = false;
        // go through all resources within the given group
        for (Resource resource : group.getResources()) {
            // check for the correct type
            resourceType = resource.getType();
            switch (resourceType) {
            case InstallableResource.TYPE_CONFIG:
                if (!configuration.checkConfigurations()) {
                    LOG.debug("Skip resource '{}', configuration checks are disabled", resource.getEntityId());
                    return "";
                }
                break;
            case InstallableResource.TYPE_BUNDLE:
                if (!configuration.checkBundles()) {
                    LOG.debug("Skip resource '{}', bundle checks are disabled", resource.getEntityId());
                    return "";
                }
                break;
            default:
                LOG.debug("Skip resource '{}' as it is neither a bundle nor a configuration but a {}",
                        resource.getEntityId(), resourceType);
                return "";
            }
            if (StringUtils.startsWithAny(resource.getURL(), configuration.urlPrefixes())) {
                isGroupRelevant = true;
                switch (resource.getState()) {
                case IGNORED: // means a considered resource was found and it is invalid
                    // still the other resources need to be evaluated
                case INSTALL:
                    if (!configuration.allowIgnoredArtifactsInGroup()) {
                        reportInvalidResource(resource, resourceType, hcLog);
                    } else {
                        if (invalidResource == null) {
                            invalidResource = resource;
                        }
                    }
                    break;
                default:
                    if (configuration.allowIgnoredArtifactsInGroup()) {
                        // means a considered resource was found and it is valid
                        // no need to evaluate other resources from this group
                        return resourceType;
                    }
                }
            } else {
                LOG.debug("Skipping resource '{}' as its URL is not starting with any of these prefixes'{}'", resource,
                        StringUtils.join(configuration.urlPrefixes(), ","));
            }
        }
        if (invalidResource != null && configuration.allowIgnoredArtifactsInGroup()) {
            reportInvalidResource(invalidResource, resourceType, hcLog);
        }
        
        // only return resource type if at least one resource in it belonged to a covered url prefix
        return isGroupRelevant ? resourceType : "";
    }

    private void reportInvalidResource(Resource invalidResource, String resourceType, FormattingResultLog hcLog) {
        if (skipEntityIdsWithVersions.containsKey(invalidResource.getEntityId())) {
            Version version = skipEntityIdsWithVersions.get(invalidResource.getEntityId());
            if (version != null) {
                if (version.equals(invalidResource.getVersion())) {
                    LOG.debug("Skipping not installed resource '{}' as its entity id and version is in the skip list", invalidResource);
                    return;
                }
            } else {
                LOG.debug("Skipping not installed resource '{}' as its entity id is in the skip list", invalidResource);
                return;
            }
        }
        if (resourceType.equals(InstallableResource.TYPE_CONFIG)) {
            hcLog.critical(
                    "The installer state of the OSGi configuration resource '{}' is {}, config might have been manually overwritten!",
                    invalidResource, invalidResource.getState());
        } else {
            hcLog.critical(
                    "The installer state of the OSGi bundle resource '{}' is {}, probably because a later or the same version of that bundle is already installed!",
                    invalidResource, invalidResource.getState());
        }
    }
}
