/*
 * 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.ignite.ci.web.rest.monitoring;

import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.CacheMetrics;
import org.apache.ignite.cache.affinity.Affinity;
import org.apache.ignite.ci.web.CtxListener;
import org.apache.ignite.ci.web.model.SimpleResult;
import org.apache.ignite.tcbot.common.interceptor.AutoProfilingInterceptor;
import org.apache.ignite.tcbot.common.interceptor.MonitoredTaskInterceptor;
import org.apache.ignite.tcbot.engine.conf.INotificationChannel;
import org.apache.ignite.tcbot.engine.conf.ITcBotConfig;
import org.apache.ignite.tcbot.engine.conf.NotificationsConfig;
import org.apache.ignite.tcbot.notify.ISlackSender;

import javax.annotation.security.PermitAll;
import javax.servlet.ServletContext;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Path("monitoring")
@Produces(MediaType.APPLICATION_JSON)
public class MonitoringService {
    /** Context. */
    @Context
    private ServletContext ctx;

    @GET
    @PermitAll
    @Path("tasks")
    public List<TaskResult> getTaskMonitoring() {
        MonitoredTaskInterceptor instance = CtxListener.getInjector(ctx).getInstance(MonitoredTaskInterceptor.class);

        final Collection<MonitoredTaskInterceptor.Invocation> list = instance.getList();

        return list.stream().map(invocation -> {
            final TaskResult res = new TaskResult();
            res.name = invocation.name();
            res.start = invocation.start();
            res.end = invocation.end();
            res.result = invocation.result();
            res.count = invocation.count();
            return res;
        }).collect(Collectors.toList());
    }


    @GET
    @PermitAll
    @Path("profiling")
    public List<HotSpot> getHotMethods() {
        AutoProfilingInterceptor instance = CtxListener.getInjector(ctx).getInstance(AutoProfilingInterceptor.class);

        Collection<AutoProfilingInterceptor.Invocation> profile = instance.getInvocations();

        Stream<HotSpot> hotSpotStream = profile.stream().map(inv -> {
            HotSpot hotSpot = new HotSpot();

            hotSpot.setTiming(inv.getNanos(), inv.getCount());
            hotSpot.method = inv.getName();

            return hotSpot;
        });

        return hotSpotStream.sorted(Comparator.comparing(HotSpot::getNanos).reversed())
                .limit(100)
                .collect(Collectors.toList());
    }

    @POST
    @Path("resetProfiling")
    public SimpleResult resetProfiling() {
        AutoProfilingInterceptor instance = CtxListener.getInjector(ctx).getInstance(AutoProfilingInterceptor.class);

        instance.reset();

        return new SimpleResult("Ok");
    }

    @POST
    @PermitAll
    @Path("testSlackNotification")
    public SimpleResult testSlackNotification() {
        ISlackSender slackSender = CtxListener.getInjector(ctx).getInstance(ISlackSender.class);

        ITcBotConfig tcBotConfig = CtxListener.getInjector(ctx).getInstance(ITcBotConfig.class);

        try {
            NotificationsConfig notifications = tcBotConfig.notifications();

            for (INotificationChannel channel : notifications.channels()) {
                if (channel.slack() != null)
                    slackSender.sendMessage(channel.slack(), "Test Slack notification message!", notifications);
            }
        }
        catch (IOException e) {
            return new SimpleResult("Failed to send test Slack message: " + e.getMessage());
        }

        return new SimpleResult("Ok");
    }


    @GET
    @PermitAll
    @Path("cacheMetrics")
    public List<CacheMetricsUi> getCacheStat() {
        Ignite ignite = CtxListener.getInjector(ctx).getInstance(Ignite.class);

        final Collection<String> strings = ignite.cacheNames();

        final ArrayList<String> cacheNames = new ArrayList<>(strings);
        cacheNames.sort(String::compareTo);

        final List<CacheMetricsUi> res = new ArrayList<>();

        for (String next : cacheNames) {
            IgniteCache<?, ?> cache = ignite.cache(next);

            if (cache == null)
                continue;
            CacheMetrics metrics = cache.metrics();

            int size = cache.size();
            float averageGetTime = metrics.getAverageGetTime();
            float averagePutTime = metrics.getAveragePutTime();

            //System.out.println(next + ": " + size + " get " + averageGetTime + " put " + averagePutTime);

            Affinity<Object> affinity = ignite.affinity(next);

            res.add(new CacheMetricsUi(next, size, affinity.partitions()));
        }
        return res;
    }
}
