import {testList, ignoredTests} from '../build/reftests';
// @ts-ignore
import {default as platform} from 'platform';
// @ts-ignore
import Promise from 'es6-promise';

const testRunnerUrl = location.href;
const hasHistoryApi = typeof window.history !== 'undefined' && typeof window.history.replaceState !== 'undefined';

const uploadResults = (canvas: HTMLCanvasElement, url: string) => {
    return new Promise((resolve: () => void, reject: (error: string) => void) => {
        // @ts-ignore
        const xhr = 'withCredentials' in new XMLHttpRequest() ? new XMLHttpRequest() : new XDomainRequest();

        xhr.onload = () => {
            if (typeof xhr.status !== 'number' || xhr.status === 200) {
                resolve();
            } else {
                reject(`Failed to send screenshot with status ${xhr.status}`);
            }
        };
        xhr.onerror = reject;

        xhr.open('POST', 'http://localhost:8000/screenshot', true);
        xhr.send(
            JSON.stringify({
                screenshot: canvas.toDataURL(),
                test: url,
                platform: {
                    name: platform.name,
                    version: platform.version
                },
                devicePixelRatio: window.devicePixelRatio || 1,
                windowWidth: window.innerWidth,
                windowHeight: window.innerHeight
            })
        );
    });
};

testList
    .filter(test => {
        return !Array.isArray(ignoredTests[test]) || ignoredTests[test].indexOf(platform.name || '') === -1;
    })
    .forEach(url => {
        describe(url, function() {
            this.timeout(60000);
            this.retries(2);
            const windowWidth = 800;
            const windowHeight = 600;
            const testContainer = document.createElement('iframe');
            testContainer.width = windowWidth.toString();
            testContainer.height = windowHeight.toString();
            testContainer.style.visibility = 'hidden';
            testContainer.style.position = 'fixed';
            testContainer.style.left = '10000px';

            before(done => {
                testContainer.onload = () => done();

                testContainer.src = url + '?selenium&run=false&reftest&' + Math.random();
                if (hasHistoryApi) {
                    // Chrome does not resolve relative background urls correctly inside of a nested iframe
                    try {
                        history.replaceState(null, '', url);
                    } catch (e) {}
                }

                document.body.appendChild(testContainer);
            });
            after(() => {
                if (hasHistoryApi) {
                    try {
                        history.replaceState(null, '', testRunnerUrl);
                    } catch (e) {}
                }
                document.body.removeChild(testContainer);
            });
            it('Should render untainted canvas', () => {
                const contentWindow = testContainer.contentWindow;
                if (!contentWindow) {
                    throw new Error('Window not found for iframe');
                }

                return (
                    contentWindow
                        // @ts-ignore
                        .html2canvas(contentWindow.forceElement || contentWindow.document.documentElement, {
                            removeContainer: true,
                            backgroundColor: '#ffffff',
                            proxy: 'http://localhost:8081/proxy',
                            // @ts-ignore
                            ...(contentWindow.h2cOptions || {})
                        })
                        .then((canvas: HTMLCanvasElement) => {
                            try {
                                (canvas.getContext('2d') as CanvasRenderingContext2D).getImageData(
                                    0,
                                    0,
                                    canvas.width,
                                    canvas.height
                                );
                            } catch (e) {
                                return Promise.reject('Canvas is tainted');
                            }

                            // @ts-ignore
                            if (window.__karma__) {
                                return uploadResults(canvas, url);
                            }
                        })
                );
            });
        });
    });