/*
 * 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.feature.extension.apiregions.analyser;

import java.util.Collection;
import java.util.Formatter;

import org.apache.sling.feature.analyser.task.AnalyserTaskContext;
import org.apache.sling.feature.extension.apiregions.api.ApiExport;
import org.apache.sling.feature.extension.apiregions.api.ApiRegion;
import org.apache.sling.feature.extension.apiregions.api.ApiRegions;
import org.apache.sling.feature.scanner.BundleDescriptor;
import org.apache.sling.feature.scanner.FeatureDescriptor;
import org.apache.sling.feature.scanner.PackageInfo;

public class CheckApiRegions extends AbstractApiRegionsAnalyserTask {

    @Override
    public String getId() {
        return ApiRegions.EXTENSION_NAME;
    }

    @Override
    public String getName() {
        return "Api Regions analyser task that checks that listed packages are actually exported";
    }

    @Override
    protected void execute(ApiRegions apiRegions, AnalyserTaskContext ctx) throws Exception {
        // for each bundle, get the Export-Package and process the packages

        FeatureDescriptor featureDescriptor = ctx.getFeatureDescriptor();
        for (BundleDescriptor bundleDescriptor : featureDescriptor.getBundleDescriptors()) {
            for (PackageInfo packageInfo : bundleDescriptor.getExportedPackages()) {
                String exportedPackage = packageInfo.getName();
                // use the Sieve technique: remove bundle exported packages from the api-regions
                for (final ApiRegion region : apiRegions.listRegions()) {
                    ApiExport export = region.getExportByName(exportedPackage);
                    if (export != null) {
                        region.remove(export);
                    }
                }
            }
        }

        boolean isEmpty = true;
        for (final ApiRegion region : apiRegions.listRegions()) {
            if (!region.listExports().isEmpty()) {
                isEmpty = false;
                break;
            }
        }
        // final evaluation: if the Sieve is not empty, not all declared packages are exported by bundles of the same feature
        if (!isEmpty) {
            // track a single error for each region
            for (ApiRegion region : apiRegions.listRegions()) {
                if (!region.listExports().isEmpty()) {
                    Formatter formatter = new Formatter();
                    formatter.format("Region '%s' defined in feature '%s' declares %s package%s which %s not exported by any bundle:%n",
                            region.getName(),
                                     ctx.getFeature().getId(),
                            region.listExports().size(), getExtension(region.listExports(), "", "s"),
                            getExtension(region.listExports(), "is", "are"));
                    region.listExports().forEach(api -> formatter.format(" * %s%n", api.getName()));

                    ctx.reportError(formatter.toString());

                    formatter.close();
                }
            }
        }
    }

    // utility methods

    private static <T> String getExtension(Collection<T> collection, String singular, String plural) {
        return collection.size() > 1 ? plural : singular;
    }

}
