const $ = require('jquery');
const FileSystemReader = require('../../plugins/formats/read/file_system_reader');
const { Job } = require('../../core/job');
const { JobFileUIHelper } = require('./job_file_ui_helper');
const { PackageOperation } = require('../../core/package_operation');
const path = require('path');
const Templates = require('../common/templates');
const { UITestUtil } = require('../common/ui_test_util');

const sourceFiles = [
    path.resolve(path.join(__dirname, '..', '..', 'test', 'bags')),
    path.resolve(path.join(__dirname, '..', '..', 'test', 'fixtures')),
    path.resolve(path.join(__dirname, '..', '..', 'test', 'profiles', 'multi_manifest.json'))
];

const extraFile = path.resolve(path.join(__dirname, '..', '..', 'test', 'profiles', 'invalid_profile.json'));
const extraDir = path.resolve(path.join(__dirname, '..', '..', 'plugins'));

function getJobWithFiles() {
    let job = new Job();
    job.packageOp = new PackageOperation('bag.tar', 'tmp/bag.tar');
    job.packageOp.sourceFiles = sourceFiles.slice();
    return job;
}

function setHTML(job) {
    let html = Templates.jobFiles({ job: job })
    let response = {
        nav: Templates.nav({ section: 'Job' }),
        container: html
    }
    UITestUtil.setDocumentBody(response);
}

test('constructor', () => {
    let job = getJobWithFiles();
    let helper = new JobFileUIHelper(job);
    expect(helper.job).toEqual(job);
});

test('initUI', () => {
    let job = getJobWithFiles();
    setHTML(job);
    let helper = new JobFileUIHelper(job);
    helper.initUI();
    let dropZoneEventListeners = $._data($('#dropZone')[0], "events");
    for (let event of ['dragover', 'dragend', 'dragleave', 'drop']) {
        expect(dropZoneEventListeners[event]).toBeDefined();
        expect(typeof dropZoneEventListeners[event][0].handler).toEqual('function');
    }
    let deleteListeners = $._data($('#filesTable')[0], "events");
    expect(deleteListeners).toBeDefined();
    expect(typeof deleteListeners.click[0].handler).toEqual('function');
    expect(deleteListeners.click[0].selector).toEqual('td.delete-file');
});

test('addItemsToUI()', done => {
    let job = getJobWithFiles();
    setHTML(job);
    let helper = new JobFileUIHelper(job);
    helper.initUI(); // this calls addItemsToUI() internally
    setTimeout(function() {
        let html = $('#filesPanel').html();
        for (let filepath of job.packageOp.sourceFiles) {
            expect(html).toContain(filepath);
        }
        let dirCount = $('#totalDirCount');
        let fileCount = $('#totalFileCount');
        let byteCount = $('#totalByteCount');
        expect(parseInt(dirCount.text(), 10)).toBeGreaterThan(0);
        expect(parseInt(fileCount.text(), 10)).toBeGreaterThan(0);
        expect(byteCount.html()).toMatch(/K|MB/);
        expect(parseInt(byteCount.data('total'), 10)).toBeGreaterThan(0);
        done();
    }, 200); // We have no event to wait for...
});

test('dropping a file adds it to the UI and job', done => {
    let job = getJobWithFiles();
    setHTML(job);
    let helper = new JobFileUIHelper(job);
    helper.initUI();
    let dropZoneEventListeners = $._data($('#dropZone')[0], "events");
    let dropEventHandler = dropZoneEventListeners.drop[0].handler;
    let mockEvent = {
        originalEvent: {
            dataTransfer: {
                files: [
                    { path: extraFile },
                    { path: extraDir }
                ]
            }
        },
        preventDefault: function() {},
        stopPropagation: function() {},
    }
    let allFiles = sourceFiles.concat([extraFile,extraDir]);
    // Call the handler
    dropEventHandler(mockEvent);
    setTimeout(function() {
        let html = $('#filesPanel').html();
        let rows = $('tr.filepath');
        let deleteCells = $('td.delete-file');
        expect(rows.length).toEqual(allFiles.length);
        expect(deleteCells.length).toEqual(allFiles.length);
        for (let filepath of allFiles) {
            expect(html).toMatch(filepath);
        }
        done();
    }, 150);
});

test('deleting a file removes it from the UI and job', () => {

});

@@ -3842,16 +3842,66 @@
 -file');
+%0A%0A        // Make sure files were added to the UI.
 %0A       
@@ -4107,105 +4107,1148 @@
   %7D%0A
-        done();%0A    %7D, 150);%0A%7D);%0A%0Atest('deleting a file removes it from the UI and job', () =%3E %7B%0A
+%0A        // Make sure files were added to the job itself.%0A        expect(job.packageOp.sourceFiles.length).toEqual(allFiles.length);%0A        done();%0A    %7D, 150);%0A%7D);%0A%0Atest('deleting a file removes it from the UI and job', done =%3E %7B%0A    let job = getJobWithFiles();%0A    setHTML(job);%0A    let helper = new JobFileUIHelper(job);%0A    helper.initUI();%0A    let deleteEventHandler = $._data($('#filesTable')%5B0%5D, %22events%22).click%5B0%5D.handler;%0A    let mockEvent = %7B%0A        currentTarget: $('td.delete-file')%0A    %7D%0A    let pathToDelete = $('td.delete-file').data('filepath');%0A    deleteEventHandler(mockEvent);%0A%0A    setTimeout(function() %7B%0A        let html = $('#filesPanel').html();%0A        let rows = $('tr.filepath');%0A        let deleteCells = $('td.delete-file');%0A%0A        // Make sure file was removed from the UI.%0A        expect(rows.length).toEqual(2);%0A        expect(deleteCells.length).toEqual(2);%0A        expect(html).not.toMatch(pathToDelete);%0A%0A        // Make sure file/dir was deleted from the job.%0A        // We started with 3, should now have two.%0A        expect(job.packageOp.sourceFiles.length).toEqual(2);%0A        done();%0A    %7D, 50);
 %0A%7D);

Test Job file deletion UI