/*
 * 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.commons.metrics.rrd4j.impl;

import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.ScheduledReporter;

import org.apache.felix.inventory.Format;
import org.apache.felix.inventory.InventoryPrinter;
import org.apache.felix.inventory.ZipAttachmentProvider;
import org.osgi.framework.BundleContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
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;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static org.apache.sling.commons.metrics.rrd4j.impl.RRD4JReporter.DEFAULT_PATH;
import static org.apache.sling.commons.metrics.rrd4j.impl.RRD4JReporter.DEFAULT_STEP;

@Component(
        immediate = true,
        configurationPolicy = ConfigurationPolicy.REQUIRE,
        service = {InventoryPrinter.class, ZipAttachmentProvider.class},
        property = {
                InventoryPrinter.NAME + "=rrd4j-reporter",
                InventoryPrinter.TITLE + "=Sling Metrics RRD4J reporter",
                InventoryPrinter.FORMAT + "=TEXT"
        }
)
@Designate(ocd = CodahaleMetricsReporter.Configuration.class)
public class CodahaleMetricsReporter implements InventoryPrinter, ZipAttachmentProvider {

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

    private Configuration configuration;
    private File rrd;
    private ScheduledReporter reporter;

    private Map<String, CopyMetricRegistryListener> listeners = new ConcurrentHashMap<>();

    @ObjectClassDefinition(name = "Apache Sling Metrics reporter writing to RRD4J",
            description = "For syntax details on RRD data-source and round " +
                    "robin archive definitions see " +
                    "https://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html and " +
                    "https://github.com/rrd4j/rrd4j/wiki/Tutorial. Changing " +
                    "any attribute in this configuration will replace an " +
                    "existing RRD file with a empty one!")
    public @interface Configuration {

        @AttributeDefinition(
                name = "Data sources",
                description = "RRDTool data source definitions " +
                        "(e.g. 'DS:oak_SESSION_LOGIN_COUNTER:COUNTER:300:0:U'). " +
                        "Replace colon characters in the metric name with an " +
                        "underscore!"
        )
        String[] datasources() default {};

        @AttributeDefinition(
                name = "Step",
                description = "The base interval in seconds with which data " +
                        "will be fed into the RRD"
        )
        int step() default DEFAULT_STEP;

        @AttributeDefinition(
                name = "Archives",
                description = "RRDTool round robin archive definitions. The " +
                        "default configuration defines four archives based " +
                        "on a default step of five seconds: " +
                        "1) per minute averages for six hours, " +
                        "2) per five minute averages 48 hours, " +
                        "3) per hour averages for four weeks, " +
                        "4) per day averages for one year."
        )
        String[] archives() default {
            "RRA:AVERAGE:0.5:12:360", "RRA:AVERAGE:0.5:60:576", "RRA:AVERAGE:0.5:720:336", "RRA:AVERAGE:0.5:17280:365"
        };

        @AttributeDefinition(
                name = "Path",
                description = "Path of the RRD file where metrics are stored. " +
                        "If the path is relative, it is resolved relative to " +
                        "the value of the framework property 'sling.home' when " +
                        "available, otherwise relative to the current working " +
                        "directory."
        )
        String path() default DEFAULT_PATH;
    }

    private MetricRegistry metricRegistry = new MetricRegistry();

    @Activate
    void activate(BundleContext context, Configuration config) throws Exception {
        LOG.info("Starting RRD4J Metrics reporter");
        configuration = config;
        rrd = getSafePath(context, config);
        reporter = RRD4JReporter.forRegistry(metricRegistry)
                .withPath(rrd)
                .withDatasources(config.datasources())
                .withArchives(config.archives())
                .withStep(config.step())
                .build();
        if (reporter != null) {
            reporter.start(config.step(), TimeUnit.SECONDS);
            LOG.info("Started RRD4J Metrics reporter: {}.", reporter);
        } else {
            LOG.warn("Illegal config will not start the RRD reporter. [path={}, datasources={}, archives={}, step={}].",
                    rrd.getPath(), config.datasources(), config.archives(), config.step());
        }
    }

    private static File getSafePath(BundleContext context, Configuration config) {
        String path = config.path();
        if (path == null || path.isEmpty()) {
            path = DEFAULT_PATH;
        }
        File rrd = new File(path);
        if (!rrd.isAbsolute()) {
            String home = context.getProperty("sling.home");
            if (home != null) {
                rrd = new File(home, rrd.getPath());
            }
        }
        return rrd;
    }

    @Deactivate
    void deactivate() {
        LOG.info("Stopping RRD4J Metrics reporter");
        if (reporter != null) {
            reporter.stop();
            reporter = null;
        }
        configuration = null;
        rrd = null;
        LOG.info("Stopped RRD4J Metrics reporter");
    }

    @Reference(
            service = MetricRegistry.class,
            cardinality = ReferenceCardinality.MULTIPLE,
            policy = ReferencePolicy.DYNAMIC)
    synchronized void addMetricRegistry(MetricRegistry metricRegistry,
                                        Map<String, Object> properties) {
        String name = (String) properties.get("name");
        if (name == null) {
            name = metricRegistry.toString();
        }
        CopyMetricRegistryListener listener = new CopyMetricRegistryListener(this.metricRegistry, name);
        listener.start(metricRegistry);
        this.listeners.put(name, listener);
        LOG.info("Bound Metrics Registry {} ",name);
    }

    synchronized void removeMetricRegistry(MetricRegistry metricRegistry,
                                           Map<String, Object> properties) {
        String name = (String) properties.get("name");
        if (name == null) {
            name = metricRegistry.toString();
        }
        CopyMetricRegistryListener metricRegistryListener = listeners.get(name);
        if ( metricRegistryListener != null) {
            metricRegistryListener.stop(metricRegistry);
            this.listeners.remove(name);
        }
        LOG.info("Unbound Metrics Registry {} ",name);
    }

    //------------------------< InventoryPrinter >------------------------------

    @Override
    public void print(PrintWriter pw, Format format, boolean isZip) {
        if (format == Format.TEXT) {
            pw.println("Sling Metrics RRD4J reporter");
            pw.println("Path: " + rrd.getAbsolutePath());
            pw.println("Step: " + configuration.step());
            pw.println("Datasources: " + Arrays.asList(configuration.datasources()));
            pw.println("Archives: " + Arrays.asList(configuration.archives()));
        }
    }

    //----------------------< ZipAttachmentProvider >---------------------------

    @Override
    public void addAttachments(ZipOutputStream zos, String namePrefix)
            throws IOException {
        if (rrd.exists()) {
            appendFile(zos, rrd, namePrefix + configuration.path());
        }
        File props = new File(rrd.getParentFile(), rrd.getName() + ".properties");
        if (props.exists()) {
            appendFile(zos, props, namePrefix + configuration.path() + ".properties");
        }
    }

    private void appendFile(ZipOutputStream zos, File file, String name)
            throws IOException {
        ZipEntry entry = new ZipEntry(name);
        entry.setSize(file.length());
        zos.putNextEntry(entry);
        try {
            Files.copy(file.toPath(), zos);
            zos.flush();
        } finally {
            zos.closeEntry();
        }
    }
}
