const REPORT_URL = 'http://localhost:8081/report_gold_data'
// Set this to enforce that the gold server must be up.
// Typically used for debugging.
const fail_on_no_gold = false;

function reportCanvas(canvas, testname, outputType='canvas') {
    let b64 = canvas.toDataURL('image/png');
    return _report(b64, outputType, testname);
}

function reportSVG(svg, testname) {
    // This converts an SVG to a base64 encoded PNG. It basically creates an
    // <img> element that takes the inlined SVG and draws it on a canvas.
    // The trick is we have to wait until the image is loaded, thus the Promise
    // wrapping below.
    let svgStr = svg.outerHTML;
    let tempImg = document.createElement('img');

    let tempCanvas = document.createElement('canvas');
    let canvasCtx = tempCanvas.getContext('2d');
    setCanvasSize(canvasCtx, svg.getAttribute('width'), svg.getAttribute('height'));

    return new Promise(function(resolve, reject) {
        tempImg.onload = () => {
            canvasCtx.drawImage(tempImg, 0, 0);
            let b64 = tempCanvas.toDataURL('image/png');
            _report(b64, 'svg', testname).then(() => {
                resolve();
            }).catch((e) => reject(e));
        };
        tempImg.setAttribute('src', 'data:image/svg+xml;,' + svgStr);
    });
}

// For tests that just do a simple path and return it as a string, wrap it in
// a proper svg and send it off.  Supports fill (nofill means just stroke it).
// This uses the "standard" size of 600x600.
function reportSVGString(svgstr, testname, fillRule='nofill') {
    let newPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    newPath.setAttribute('stroke', 'black');
    if (fillRule !== 'nofill') {
        newPath.setAttribute('fill', 'orange');
        newPath.setAttribute('fill-rule', fillRule);
    } else {
        newPath.setAttribute('fill', 'rgba(255,255,255,0.0)');
    }
    newPath.setAttribute('d', svgstr);
    let newSVG = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    newSVG.appendChild(newPath);
    // helps with the conversion to PNG.
    newSVG.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
    newSVG.setAttribute('width', 600);
    newSVG.setAttribute('height', 600);
    return reportSVG(newSVG, testname);
}

// Reports a canvas and then an SVG of this path. Puts it on a standard size canvas.
function reportPath(path, testname, done) {
    let canvas = document.createElement('canvas');
    let canvasCtx = canvas.getContext('2d');
    // Set canvas size and make it a bit bigger to zoom in on the lines
    standardizedCanvasSize(canvasCtx);
    canvasCtx.stroke(path.toPath2D());

    let svgStr = path.toSVGString();

    return reportCanvas(canvas, testname).then(() => {
                reportSVGString(svgStr, testname).then(() => {
                    done();
                }).catch(reportError(done));
            }).catch(reportError(done));
}

// data is a base64 encoded png, outputType is the value that goes with the
// key 'config' when reporting.
function _report(data, outputType, testname) {
    return fetch(REPORT_URL, {
        method: 'POST',
        mode: 'no-cors',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            'output_type': outputType,
            'data': data,
            'test_name': testname,
        })
    }).then(() => console.log(`Successfully reported ${testname} to gold aggregator`));
}

function reportError(done) {
    return (e) => {
        console.log("Error with fetching. Likely could not connect to aggregator server", e.message);
        if (fail_on_no_gold) {
            expect(e).toBeUndefined();
        }
        done();
    };
}

function setCanvasSize(ctx, width, height) {
    ctx.canvas.width = width;
    ctx.canvas.height = height;
}

function standardizedCanvasSize(ctx) {
    setCanvasSize(ctx, 600, 600);
}

// A wrapper to catch and print a stacktrace to the logs.
// Exceptions normally shows up in the browser console,
// but not in the logs that appear on the bots AND a thrown
// exception will normally cause a test to time out.
// This wrapper mitigates both those pain points.
function catchException(done, fn) {
    return () => {
        try {
            fn()
        } catch (e) {
            console.log('Failed with the following error', e);
            expect(e).toBeFalsy();
            debugger;
            done();
        }
        // We don't call done with finally because
        // that would make the break the asynchronous nature
        // of fn().
    }
}
