package org.jenkinsci.plugins.statusbadges;

import jenkins.model.Jenkins;

import org.apache.commons.io.IOUtils;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import javax.servlet.ServletException;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
import java.util.HashMap;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Canvas;
import java.awt.FontFormatException;

import static javax.servlet.http.HttpServletResponse.*;

class StatusImage
    implements HttpResponse
{
    private final String payload;

    private final String etag;

    private final String length;

    private final Map<String, String> colors = new HashMap<String, String>()
    {
        private static final long serialVersionUID = 1L;

        {
            put( "red", "#e05d44" );
            put( "brightgreen", "#44cc11" );
            put( "green", "#97CA00" );
            put( "yellowgreen", "#a4a61d" );
            put( "yellow", "#dfb317" );
            put( "orange", "#fe7d37" );
            put( "lightgrey", "#9f9f9f" );
            put( "blue", "#007ec6" );
        };
    };

    StatusImage( String subject, String status, String colorName, String style )
        throws FontFormatException, IOException
    {
        etag = Jenkins.RESOURCE_PATH + '/' + subject + status + colorName;

        if ( style == null )
        {
            style = "default";
        }

        URL image =
            new URL( Jenkins.getInstance().pluginManager.getPlugin( "status-badges" ).baseResourceURL, "status/"
                + style + ".svg" );
        InputStream s = image.openStream();

        double[] widths = { measureText( subject ) + 10, measureText( status ) + 10 };

        String color = colors.get( colorName );

        if ( color == null )
        {
            color = '#' + colorName;
        }

        String fullwidth = String.valueOf( widths[0] + widths[1] );
        String blockPos = String.valueOf( widths[0] );
        String blockWidth = String.valueOf( widths[1] );
        String subjectPos = String.valueOf( ( widths[0] / 2 ) + 1 );
        String statusPos = String.valueOf( widths[0] + ( widths[1] / 2 ) - 1 );

        try
        {
            payload =
                IOUtils.toString( s, "utf-8" ).replace( "{{fullwidth}}", fullwidth ).replace( "{{blockPos}}", blockPos ).replace( "{{blockWidth}}",
                                                                                                                                  blockWidth ).replace( "{{subjectPos}}",
                                                                                                                                                        subjectPos ).replace( "{{statusPos}}",
                                                                                                                                                                              statusPos ).replace( "{{subject}}",
                                                                                                                                                                                                   subject ).replace( "{{status}}",
                                                                                                                                                                                                                      status ).replace( "{{color}}",
                                                                                                                                                                                                                                        color );
        }
        finally
        {
            IOUtils.closeQuietly( s );
        }

        length = Integer.toString( payload.length() );
    }

    public int measureText( String text )
        throws FontFormatException, IOException
    {
        URL fontURL =
            new URL( Jenkins.getInstance().pluginManager.getPlugin( "status-badges" ).baseResourceURL,
                     "fonts/verdana.ttf" );
        InputStream fontStream = fontURL.openStream();
        Font defaultFont = Font.createFont( Font.TRUETYPE_FONT, fontStream );
        defaultFont = defaultFont.deriveFont( 11f );
        Canvas canvas = new Canvas();
        FontMetrics fontMetrics = canvas.getFontMetrics( defaultFont );
        return fontMetrics.stringWidth( text );
    }

    @Override
    public void generateResponse( StaplerRequest req, StaplerResponse rsp, Object node )
        throws IOException, ServletException
    {
        String v = req.getHeader( "If-None-Match" );
        if ( etag.equals( v ) )
        {
            rsp.setStatus( SC_NOT_MODIFIED );
            return;
        }

        rsp.setHeader( "ETag", etag );
        rsp.setHeader( "Expires", "Fri, 01 Jan 1984 00:00:00 GMT" );
        rsp.setHeader( "Cache-Control", "no-cache, private" );
        rsp.setHeader( "Content-Type", "image/svg+xml;charset=utf-8" );
        rsp.setHeader( "Content-Length", length );
        rsp.getOutputStream().write( payload.getBytes() );
    }
}