package cz.martinstainer.visualiser;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;

import cz.martinstainer.chart.ThroughputChart;

import org.apache.jmeter.assertions.AssertionResult;
import org.apache.jmeter.samplers.Clearable;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jmeter.visualizers.gui.AbstractVisualizer;

public class ThroughputGraphVisualiser extends AbstractVisualizer implements Clearable {

    private static final long serialVersionUID = 240L;
    private ThroughputChart throughputChart;
    private JTextArea textArea;
    private JComboBox yUnits;
    private JComboBox xUnits;
    private JCheckBox customCheckbox;
    private JTextField customXUnit;
    private JTextField customXValue;

    private String unit = "m";

    public ThroughputGraphVisualiser() {
        init();
        setName(getStaticLabel());
    }

    @Override
    public String getLabelResource() {
        return "Throughput graph visualiser"; // $NON-NLS-1$
    }

    @Override
    @SuppressWarnings("SynchronizeOnNonFinalField")
    public void add(SampleResult sample) {
        final StringBuilder sb = new StringBuilder(100);
        if (sample.getResponseCode() != "0") {
            throughputChart.addValueToChartData(
                    (float) (sample.getStartTime() - sample.getEndTime()),
                    (float) (sample.getSentBytes()),
                    sample.getContentType()
            );
        }
        sb.append(sample.getSampleLabel());
        sb.append(getAssertionResult(sample));
        sb.append("\n"); // $NON-NLS-1$
        JMeterUtils.runSafe(false, () -> {
            synchronized (textArea) {
                textArea.append(sb.toString());
                textArea.setCaretPosition(textArea.getText().length());
            }
        });
    }

    @Override
    public void clearData() {
        textArea.setText(""); // $NON-NLS-1$
    }

    private String getAssertionResult(SampleResult res) {
        if (res != null) {
            StringBuilder display = new StringBuilder();
            AssertionResult[] assertionResults = res.getAssertionResults();
            for (AssertionResult item : assertionResults) {
                if (item.isFailure() || item.isError()) {
                    display.append("\n\t"); // $NON-NLS-1$
                    display.append(item.getName() != null ? item.getName() + " : " : "");// $NON-NLS-1$
                    display.append(item.getFailureMessage());
                }
            }
            return display.toString();
        }
        return "";
    }

    private void init() {
        this.setLayout(new BorderLayout());
        // MAIN PANEL
        Border margin = new EmptyBorder(10, 10, 5, 10);
        this.setBorder(margin);
        this.throughputChart = new ThroughputChart();
        this.add(throughputChart,BorderLayout.NORTH);
        JLabel textAreaLabel =
        new JLabel(JMeterUtils.getResString("test")); // $NON-NLS-1$
        textAreaLabel.setLabelFor(textArea);
        Box mainPanel = Box.createVerticalBox();
        textArea = new JTextArea();
        textArea.setEditable(false);
        textArea.setLineWrap(false);
        JScrollPane areaScrollPane = new JScrollPane(textArea);
        areaScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        areaScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        areaScrollPane.setPreferredSize(new Dimension(mainPanel.getWidth(),mainPanel.getHeight()));
        mainPanel.add(areaScrollPane);
        JButton button = new JButton("Erase chart");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e){
                throughputChart.eraseData();
            }
        });
        JPanel controls = new JPanel(new FlowLayout(FlowLayout.LEFT));
        customCheckbox = new JCheckBox("Custom unit and value.");
        customXUnit = new JTextField();
        customXUnit.setColumns(20);
        customXValue = new JTextField();
        customXValue.setColumns(20);
        JButton xCustomUnitButton = new JButton("Set custom");
        xCustomUnitButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e){
                throughputChart.setCustom(customXUnit.getText(), Float.valueOf(customXValue.getText()));
            }
        });
        String s1[] = { "Kbit/s", "Mbit/s", "Gbit/s"};
        xUnits = new JComboBox(s1);
        xUnits.setSelectedIndex(1);
        JButton xUnitButton = new JButton("Change unit");
        xUnitButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e){
                throughputChart.recalculate((String) xUnits.getSelectedItem());
            }
        });
        controls.add(xUnits);
        controls.add(xUnitButton);
        controls.add(button);
        this.add(controls, BorderLayout.LINE_END);
    }
}
