/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * Licensed 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 com.alibaba.dubbo.monitor.simple;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import javax.imageio.ImageIO;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Minute;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.URL;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.common.utils.ConfigUtils;
import com.alibaba.dubbo.common.utils.NamedThreadFactory;
import com.alibaba.dubbo.common.utils.NetUtils;
import com.alibaba.dubbo.monitor.MonitorService;

/**
 * SimpleMonitorService
 * 
 * @author william.liangf
 */
public class SimpleMonitorService implements MonitorService {

    private static final Logger logger = LoggerFactory.getLogger(SimpleMonitorService.class);

    private static final String[] types = {SUCCESS, FAILURE, ELAPSED, CONCURRENT, MAX_ELAPSED, MAX_CONCURRENT};
    
    private static final String POISON_PROTOCOL = "poison";
    
    // 定时任务执行器
    private final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1, new NamedThreadFactory("DubboMonitorTimer", true));

    // 图表绘制定时器
    private final ScheduledFuture<?> chartFuture;

    private final Thread writeThread;
    
    private final BlockingQueue<URL> queue;
    
    private String statisticsDirectory = "statistics";

    private String chartsDirectory = "charts";
    
    private volatile boolean running = true;
    
    private static SimpleMonitorService INSTANCE = null;

    public static SimpleMonitorService getInstance() {
        return INSTANCE;
    }

    public String getStatisticsDirectory() {
        return statisticsDirectory;
    }
    
    public void setStatisticsDirectory(String statistics) {
        if (statistics != null) {
            this.statisticsDirectory = statistics;
        }
    }

    public String getChartsDirectory() {
        return chartsDirectory;
    }

    public void setChartsDirectory(String charts) {
        if (charts != null) {
            this.chartsDirectory = charts;
        }
    }
    
    public SimpleMonitorService() {
        queue = new LinkedBlockingQueue<URL>(Integer.parseInt(ConfigUtils.getProperty("dubbo.monitor.queue", "100000")));
        writeThread = new Thread(new Runnable() {
            public void run() {
                while (running) {
                    try {
                        write(); // 记录统计日志
                    } catch (Throwable t) { // 防御性容错
                        logger.error("Unexpected error occur at write stat log, cause: " + t.getMessage(), t);
                        try {
                            Thread.sleep(5000); // 失败延迟
                        } catch (Throwable t2) {
                        }
                    }
                }
            }
        });
        writeThread.setDaemon(true);
        writeThread.setName("DubboMonitorAsyncWriteLogThread");
        writeThread.start();
        chartFuture = scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            public void run() {
                try {
                    draw(); // 绘制图表
                } catch (Throwable t) { // 防御性容错
                    logger.error("Unexpected error occur at draw stat chart, cause: " + t.getMessage(), t);
                }
            }
        }, 1, 300, TimeUnit.SECONDS);
        INSTANCE = this;
    }

    public void close() {
        try {
            running = false;
            queue.offer(new URL(POISON_PROTOCOL, NetUtils.LOCALHOST, 0));
        } catch (Throwable t) {
            logger.warn(t.getMessage(), t);
        }
        try {
            chartFuture.cancel(true);
        } catch (Throwable t) {
            logger.warn(t.getMessage(), t);
        }
    }
    
    private void write() throws Exception {
        URL statistics = queue.take();
        if (POISON_PROTOCOL.equals(statistics.getProtocol())) {
            return;
        }
        String timestamp = statistics.getParameter(Constants.TIMESTAMP_KEY);
        Date now;
        if (timestamp == null || timestamp.length() == 0) {
            now = new Date();
        } else if (timestamp.length() == "yyyyMMddHHmmss".length()) {
            now = new SimpleDateFormat("yyyyMMddHHmmss").parse(timestamp);
        } else {
            now = new Date(Long.parseLong(timestamp));
        }
        String day = new SimpleDateFormat("yyyyMMdd").format(now);
        SimpleDateFormat format = new SimpleDateFormat("HHmm");
        for (String key : types) {
            try {
                String type;
                String consumer;
                String provider;
                if (statistics.hasParameter(PROVIDER)) {
                    type = PROVIDER;
                    consumer = statistics.getHost();
                    provider = statistics.getParameter(PROVIDER);
                    int i = provider.indexOf(':');
                    if (i > 0) {
                        provider = provider.substring(0, i);
                    }
                } else {
                    type = CONSUMER;
                    consumer = statistics.getParameter(CONSUMER);
                    int i = consumer.indexOf(':');
                    if (i > 0) {
                        consumer = consumer.substring(0, i);
                    }
                    provider = statistics.getHost();
                }
                String filename = statisticsDirectory 
                        + "/" + day 
                        + "/" + statistics.getServiceInterface() 
                        + "/" + statistics.getParameter(METHOD) 
                        + "/" + consumer 
                        + "/" + provider 
                        + "/" + type + "." + key;
                File file = new File(filename);
                File dir = file.getParentFile();
                if (dir != null && ! dir.exists()) {
                    dir.mkdirs();
                }
                FileWriter writer = new FileWriter(file, true);
                try {
                    writer.write(format.format(now) + " " + statistics.getParameter(key, 0) + "\n");
                    writer.flush();
                } finally {
                    writer.close();
                }
            } catch (Throwable t) {
                logger.error(t.getMessage(), t);
            }
        }
    }

    private void draw() {
        File rootDir = new File(statisticsDirectory);
        if (! rootDir.exists()) {
            return;
        }
        File[] dateDirs = rootDir.listFiles();
        for (File dateDir : dateDirs) {
            File[] serviceDirs = dateDir.listFiles();
            for (File serviceDir : serviceDirs) {
                File[] methodDirs = serviceDir.listFiles();
                for (File methodDir : methodDirs) {
                    String methodUri = chartsDirectory + "/" + dateDir.getName() + "/" + serviceDir.getName() + "/" + methodDir.getName();
                    
                    File successFile = new File(methodUri + "/" + SUCCESS + ".png");
                    long successModified = successFile.lastModified();
                    boolean successChanged = false;
                    Map<String, long[]> successData = new HashMap<String, long[]>();
                    double[] successSummary = new double[4];
                    
                    File elapsedFile = new File(methodUri + "/" + ELAPSED + ".png");
                    long elapsedModified = elapsedFile.lastModified();
                    boolean elapsedChanged = false;
                    Map<String, long[]> elapsedData = new HashMap<String, long[]>();
                    double[] elapsedSummary = new double[4];
                    long elapsedMax = 0;
                    
                    File[] consumerDirs = methodDir.listFiles();
                    for (File consumerDir : consumerDirs) {
                        File[] providerDirs = consumerDir.listFiles();
                        for (File providerDir : providerDirs) {
                            File consumerSuccessFile = new File(providerDir, CONSUMER + "." + SUCCESS);
                            File providerSuccessFile = new File(providerDir, PROVIDER + "." + SUCCESS);
                            appendData(new File[] {consumerSuccessFile, providerSuccessFile}, successData, successSummary);
                            if (consumerSuccessFile.lastModified() > successModified 
                                    || providerSuccessFile.lastModified() > successModified) {
                                successChanged = true;
                            }
                            
                            File consumerElapsedFile = new File(providerDir, CONSUMER + "." + ELAPSED);
                            File providerElapsedFile = new File(providerDir, PROVIDER + "." + ELAPSED);
                            appendData(new File[] {consumerElapsedFile, providerElapsedFile}, elapsedData, elapsedSummary);
                            elapsedMax = Math.max(elapsedMax, CountUtils.max(new File(providerDir, CONSUMER + "." + MAX_ELAPSED)));
                            elapsedMax = Math.max(elapsedMax, CountUtils.max(new File(providerDir, PROVIDER + "." + MAX_ELAPSED)));
                            if (consumerElapsedFile.lastModified() > elapsedModified 
                                    || providerElapsedFile.lastModified() > elapsedModified) {
                                elapsedChanged = true;
                            }
                        }
                    }
                    if (elapsedChanged) {
                        divData(elapsedData, successData);
                        elapsedSummary[0] = elapsedMax;
                        elapsedSummary[1] = -1;
                        elapsedSummary[2] = successSummary[3] == 0 ? 0 : elapsedSummary[3] / successSummary[3];
                        elapsedSummary[3] = -1;
                        createChart("ms/t", serviceDir.getName(), methodDir.getName(), dateDir.getName(), new String[] {CONSUMER, PROVIDER}, elapsedData, elapsedSummary, elapsedFile.getAbsolutePath());
                    }
                    if (successChanged) {
                        divData(successData, 60);
                        successSummary[0] = successSummary[0] / 60;
                        successSummary[1] = successSummary[1] / 60;
                        successSummary[2] = successSummary[2] / 60;
                        createChart("t/s", serviceDir.getName(), methodDir.getName(), dateDir.getName(), new String[] {CONSUMER, PROVIDER}, successData, successSummary, successFile.getAbsolutePath());
                    }
                }
            }
        }
    }
    
    private void divData(Map<String, long[]> successMap, long unit) {
        for (long[] success : successMap.values()) {
            for (int i = 0; i < success.length; i ++) {
                success[i] = success[i] / unit;
            }
        }
    }
    
    private void divData(Map<String, long[]> elapsedMap, Map<String, long[]> successMap) {
        for (Map.Entry<String, long[]> entry : elapsedMap.entrySet()) {
            long[] elapsed = entry.getValue();
            long[] success = successMap.get(entry.getKey());
            for (int i = 0; i < elapsed.length; i ++) {
                elapsed[i] = success[i] == 0 ? 0 : elapsed[i] / success[i];
            }
        }
    }

    private void appendData(File[] files, Map<String, long[]> data, double[] summary) {
        for (int i = 0; i < files.length; i ++) {
            File file = files[i];
            if (! file.exists()) {
                continue;
            }
            try {
                BufferedReader reader = new BufferedReader(new FileReader(file));
                try {
                    int sum = 0;
                    int cnt = 0;
                    String line;
                    while ((line = reader.readLine()) != null) {
                        int index = line.indexOf(" ");
                        if (index > 0) {
                            String key = line.substring(0, index).trim();
                            long value = Long.parseLong(line.substring(index + 1).trim());
                            long[] values = data.get(key);
                            if (values == null) {
                                values = new long[files.length];
                                data.put(key, values);
                            }
                            values[i] += value;
                            summary[0] = Math.max(summary[0], values[i]);
                            summary[1] = summary[1] == 0 ? values[i] : Math.min(summary[1], values[i]);
                            sum += value;
                            cnt ++;
                        }
                    }
                    if (i == 0) {
                        summary[3] += sum;
                        summary[2] = (summary[2] + (sum / cnt)) / 2;
                    }
                } finally {
                    reader.close();
                }
            } catch (IOException e) {
                logger.warn(e.getMessage(), e);
            }
        }
    }
    
    private static void createChart(String key, String service, String method, String date, String[] types, Map<String, long[]> data, double[] summary, String path) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmm");
        DecimalFormat numberFormat = new DecimalFormat("###,##0.##");
        TimeSeriesCollection xydataset = new TimeSeriesCollection();
        for (int i = 0; i < types.length; i ++) {
            String type = types[i];
            TimeSeries timeseries = new TimeSeries(type);
            for (Map.Entry<String, long[]> entry : data.entrySet()) {
                try {
                    timeseries.add(new Minute(dateFormat.parse(date + entry.getKey())), entry.getValue()[i]);
                } catch (ParseException e) {
                    logger.error(e.getMessage(), e);
                }
            }
            xydataset.addSeries(timeseries);
        }
        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart(
                "max: " + numberFormat.format(summary[0]) + (summary[1] >=0 ? " min: " + numberFormat.format(summary[1]) : "") 
                + " avg: " + numberFormat.format(summary[2]) + (summary[3] >=0 ? " sum: " + numberFormat.format(summary[3]) : ""), 
                toDisplayService(service) + "  " + method + "  " + toDisplayDate(date), key, xydataset, true, true, false);
        jfreechart.setBackgroundPaint(Color.WHITE);
        XYPlot xyplot = (XYPlot) jfreechart.getPlot();
        xyplot.setBackgroundPaint(Color.WHITE);
        xyplot.setDomainGridlinePaint(Color.GRAY);
        xyplot.setRangeGridlinePaint(Color.GRAY);
        xyplot.setDomainGridlinesVisible(true);
        xyplot.setRangeGridlinesVisible(true);
        DateAxis dateaxis = (DateAxis) xyplot.getDomainAxis();
        dateaxis.setDateFormatOverride(new SimpleDateFormat("HH:mm"));
        BufferedImage image = jfreechart.createBufferedImage(600, 300);
        try {
            if (logger.isInfoEnabled()) {
                logger.info("write chart: " + path);
            }
            File methodChartFile = new File(path);
            File methodChartDir = methodChartFile.getParentFile();
            if (methodChartDir != null && ! methodChartDir.exists()) {
                methodChartDir.mkdirs();
            }
            FileOutputStream output = new FileOutputStream(methodChartFile);
            try {
                ImageIO.write(image, "png", output);
                output.flush();
            } finally {
                output.close();
            }
        } catch (IOException e) {
            logger.warn(e.getMessage(), e);
        }
    }
    
    private static String toDisplayService(String service) {
        int i = service.lastIndexOf('.');
        if (i >= 0) {
            return service.substring(i + 1);
        }
        return service;
    }
    
    private static String toDisplayDate(String date) {
        try {
            return new SimpleDateFormat("yyyy-MM-dd").format(new SimpleDateFormat("yyyyMMdd").parse(date));
        } catch (ParseException e) {
            return date;
        }
    }

    public void count(URL statistics) {
        queue.offer(statistics);
        if (logger.isInfoEnabled()) {
            logger.info("collect statistics: " + statistics);
        }
    }

}