/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

/* eslint-env jasmine */
var fetch = require('../index.js');
var uninstall = require('../index.js').uninstall;
var shell = require('shelljs');
var path = require('path');
var fs = require('fs');
var helpers = require('./helpers.js');

describe('platform fetch/uninstall tests via npm & git', function () {

    var tmpDir = helpers.tmpDir('plat_fetch');
    var opts = {};

    beforeEach(function () {
        process.chdir(tmpDir);
    });

    afterEach(function () {
        process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
        shell.rm('-rf', tmpDir);
    });

    it('should fetch and uninstall a cordova platform via npm & git', function (done) {

        fetch('cordova-android', tmpDir, opts)
            .then(function (result) {
                var pkgJSON = require(path.join(result, 'package.json'));
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(pkgJSON.name).toBe('cordova-android');

                return uninstall('cordova-android', tmpDir, opts);
            })
            .then(function () {
                expect(fs.existsSync(path.join(tmpDir, 'node_modules', 'cordova-android'))).toBe(false);

                return fetch('https://github.com/apache/cordova-ios.git', tmpDir, opts);
            })
            .then(function (result) {
                var pkgJSON = require(path.join(result, 'package.json'));
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(pkgJSON.name).toBe('cordova-ios');

                return uninstall('cordova-ios', tmpDir, opts);
            })
            .then(function () {
                expect(fs.existsSync(path.join(tmpDir, 'node_modules', 'cordova-ios'))).toBe(false);

                // return fetch('git+ssh://git@github.com/apache/cordova-browser.git#487d91d1ded96b8e2029f2ee90f12a8b20499f54', tmpDir, opts);
                // can't test ssh right now as it is requiring ssh password
                return fetch('https://github.com/apache/cordova-browser.git', tmpDir, opts);
            })
            .then(function (result) {
                var pkgJSON = require(path.join(result, 'package.json'));
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(pkgJSON.name).toBe('cordova-browser');
            })
            .fail(function (err) {
                console.error(err);
                expect(err).toBeUndefined();
            })
            .fin(done);
    }, 60000);
});

describe('platform fetch/uninstall test via npm & git tags with --save', function () {

    var tmpDir = helpers.tmpDir('plat_fetch_save');
    var opts = {'save': true};

    beforeEach(function () {
        // copy package.json from spec directory to tmpDir
        shell.cp('spec/testpkg.json', path.join(tmpDir, 'package.json'));
        process.chdir(tmpDir);
    });

    afterEach(function () {
        process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
        shell.rm('-rf', tmpDir);
    });

    it('should fetch and uninstall a cordova platform via npm & git tags/branches', function (done) {
        fetch('cordova-android@5.1.1', tmpDir, opts)
            .then(function (result) {
                var pkgJSON = require(path.join(result, 'package.json'));
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(pkgJSON.name).toBe('cordova-android');
                expect(pkgJSON.version).toBe('5.1.1');

                var rootPJ = require(path.join(tmpDir, 'package.json'));
                expect(rootPJ.dependencies['cordova-android']).toBe('^5.1.1');

                return uninstall('cordova-android', tmpDir, opts);
            })
            .then(function () {
                var rootPJ = JSON.parse(fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf8'));
                expect(Object.keys(rootPJ.dependencies).length).toBe(0);
                expect(fs.existsSync(path.join(tmpDir, 'node_modules', 'cordova-android'))).toBe(false);

                return fetch('https://github.com/apache/cordova-ios.git#rel/4.1.1', tmpDir, opts);
            })
            .then(function (result) {
                var pkgJSON = require(path.join(result, 'package.json'));
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(pkgJSON.name).toBe('cordova-ios');
                expect(pkgJSON.version).toBe('4.1.1');

                var rootPJ = JSON.parse(fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf8'));
                expect(rootPJ.dependencies['cordova-ios']).toBe('git+https://github.com/apache/cordova-ios.git#rel/4.1.1');

                return uninstall('cordova-ios', tmpDir, opts);
            })
            .then(function () {
                var rootPJ = JSON.parse(fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf8'));
                expect(Object.keys(rootPJ.dependencies).length).toBe(0);
                expect(fs.existsSync(path.join(tmpDir, 'node_modules', 'cordova-ios'))).toBe(false);

                return fetch('https://github.com/apache/cordova-android.git#4.1.x', tmpDir, opts);
            })
            .then(function (result) {
                var pkgJSON = JSON.parse(fs.readFileSync(path.join(result, 'package.json'), 'utf8'));
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(pkgJSON.name).toBe('cordova-android');
                expect(pkgJSON.version).toBe('4.1.1');

                var rootPJ = JSON.parse(fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf8'));
                expect(rootPJ.dependencies['cordova-android']).toBe('git+https://github.com/apache/cordova-android.git#4.1.x');

                return uninstall('cordova-android', tmpDir, opts);
            })
            .fail(function (err) {
                console.error(err);
                expect(err).toBeUndefined();
            })
            .fin(done);
    }, 150000);
});

describe('plugin fetch/uninstall test with --save', function () {

    var tmpDir = helpers.tmpDir('plug_fetch_save');
    var opts = {'save': true};

    beforeEach(function () {
        // copy package.json from spec directory to tmpDir
        shell.cp('spec/testpkg.json', path.join(tmpDir, 'package.json'));
        process.chdir(tmpDir);
    });

    afterEach(function () {
        process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
        shell.rm('-rf', tmpDir);
    });

    it('should fetch and uninstall a cordova plugin via git commit sha', function (done) {
        fetch('https://github.com/apache/cordova-plugin-contacts.git#7db612115755c2be73a98dda76ff4c5fd9d8a575', tmpDir, opts)
            .then(function (result) {
                var pkgJSON = require(path.join(result, 'package.json'));
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(pkgJSON.name).toBe('cordova-plugin-contacts');
                expect(pkgJSON.version).toBe('2.0.2-dev');

                var rootPJ = require(path.join(tmpDir, 'package.json'));
                expect(rootPJ.dependencies['cordova-plugin-contacts']).toBe('git+https://github.com/apache/cordova-plugin-contacts.git#7db612115755c2be73a98dda76ff4c5fd9d8a575');

                return uninstall('cordova-plugin-contacts', tmpDir, opts);
            })
            .then(function () {
                var rootPJ = JSON.parse(fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf8'));
                expect(Object.keys(rootPJ.dependencies).length).toBe(0);
                expect(fs.existsSync(path.join(tmpDir, 'node_modules', 'cordova-plugin-contacts'))).toBe(false);
            })
            .fail(function (err) {
                console.error(err);
                expect(err).toBeUndefined();
            })
            .fin(done);
    }, 30000);
});

describe('test trimID method for npm and git', function () {

    var tmpDir;
    var opts = {};

    beforeEach(function () {
        tmpDir = helpers.tmpDir('plug_trimID');
        process.chdir(tmpDir);
    });

    afterEach(function () {
        process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
        shell.rm('-rf', tmpDir);
    });

    it('should fetch the same cordova plugin twice in a row', function (done) {
        fetch('cordova-plugin-device', tmpDir, opts)
            .then(function (result) {
                var pkgJSON = require(path.join(result, 'package.json'));
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(pkgJSON.name).toBe('cordova-plugin-device');

                return fetch('https://github.com/apache/cordova-plugin-media.git', tmpDir, opts);
            })
            .then(function (result) {
                var pkgJSON = require(path.join(result, 'package.json'));
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(pkgJSON.name).toBe('cordova-plugin-media');

                // refetch to trigger trimID
                return fetch('cordova-plugin-device', tmpDir, opts);

            })
            .then(function (result) {
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(result).toMatch('cordova-plugin-device');

                // refetch to trigger trimID
                return fetch('https://github.com/apache/cordova-plugin-media.git', tmpDir, opts);
            })
            .then(function (result) {
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(result).toMatch('cordova-plugin-media');

                // refetch to trigger trimID, this time no .git
                return fetch('https://github.com/apache/cordova-plugin-media', tmpDir, opts);
            })
            .then(function (result) {
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(result).toMatch('cordova-plugin-media');
            })
            .fail(function (err) {
                console.error(err);
                expect(err).toBeUndefined();
            })
            .fin(done);
    }, 40000);

    it('should fetch same plugin twice in a row if git repo name differ from plugin id', function (done) {
        fetch('https://github.com/AzureAD/azure-activedirectory-library-for-cordova.git', tmpDir, opts)
            .then(function (result) {
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(result).toMatch('cordova-plugin-ms-adal');
                return fetch('https://github.com/AzureAD/azure-activedirectory-library-for-cordova.git', tmpDir, opts);
            })
            .then(function (result) {
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(result).toMatch('cordova-plugin-ms-adal');
            })
            .fail(function (err) {
                console.error(err);
                expect(err).toBeUndefined();
            })
            .fin(done);
    }, 30000);
});

describe('fetch failure with unknown module', function () {

    var tmpDir = helpers.tmpDir('fetch_fails_npm');
    var opts = {};

    beforeEach(function () {
        process.chdir(tmpDir);
    });

    afterEach(function () {
        process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
        shell.rm('-rf', tmpDir);
    });

    it('should fail fetching a module that does not exist on npm', function (done) {
        fetch('NOTAMODULE', tmpDir, opts)
            .then(function (result) {
                console.log('This should fail and it should not be seen');
            })
            .fail(function (err) {
                expect(err.message.code).toBe(1);
                expect(err).toBeDefined();
            })
            .fin(done);
    }, 30000);
});

describe('fetch failure with git subdirectory', function () {

    var tmpDir = helpers.tmpDir('fetch_fails_subdirectory');
    var opts = {};

    beforeEach(function () {
        process.chdir(tmpDir);
    });

    afterEach(function () {
        process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
        shell.rm('-rf', tmpDir);
    });

    it('should fail fetching a giturl which contains a subdirectory', function (done) {
        fetch('https://github.com/apache/cordova-plugins.git#:keyboard', tmpDir, opts)
            .then(function (result) {
                console.log('This should fail and it should not be seen');
            })
            .fail(function (err) {
                expect(err.message.code).toBe(1);
                expect(err).toBeDefined();
            })
            .fin(done);
    }, 30000);
});

describe('scoped plugin fetch/uninstall tests via npm', function () {

    var tmpDir = helpers.tmpDir('scoped_plug_fetch');
    var opts = {};

    beforeEach(function () {
        process.chdir(tmpDir);
    });

    afterEach(function () {
        process.chdir(path.join(__dirname, '..')); // Needed to rm the dir on Windows.
        shell.rm('-rf', tmpDir);
    });

    it('should fetch a scoped plugin from npm', function (done) {
        fetch('@stevegill/cordova-plugin-device', tmpDir, opts)
            .then(function (result) {
                var pkgJSON = require(path.join(result, 'package.json'));
                expect(result).toBeDefined();
                expect(fs.existsSync(result)).toBe(true);
                expect(pkgJSON.name).toBe('@stevegill/cordova-plugin-device');
            })
            .fail(function (err) {
                console.error(err);
                expect(err).toBeUndefined();
            })
            .fin(done);
    }, 30000);
});
