/**
    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.
*/

const { events } = require('cordova-common');
const cordovaUtil = require('../../../src/cordova/util');
const pluginUtil = require('../../../src/cordova/plugin/util');
const pluginAdd = require('../../../src/cordova/plugin/add');

const cordovaVersion = '3.4.2';

// Used to extract the constraint, the installed version, and the required
// semver range from a warning message
const UNMET_REQ_REGEX = /\s+([^\s]+)[^\d]+(\d+\.\d+\.\d+) in project, (.+) required\)/;

function unmetRequirementsCollector (warning) {
    const match = UNMET_REQ_REGEX.exec(warning);
    if (!match) return;

    unmetRequirementsCollector.store.push({
        dependency: match[1],
        installed: match[2],
        required: match[3]
    });
}

// Checks the warnings that were printed by the CLI to ensure that the code is
// listing the correct reasons for failure. Checks against the global warnings
// object which is reset before each test
function expectUnmetRequirements (expected) {
    const actual = unmetRequirementsCollector.store;
    expect(actual).toEqual(jasmine.arrayWithExactContents(expected));
}

// Helper functions for creating the requirements objects taken by
// expectUnmetRequirements()
function getPlatformRequirement (requirement) {
    return {
        dependency: 'cordova-android',
        installed: '3.1.0',
        required: requirement
    };
}

function getCordovaRequirement (requirement) {
    return {
        dependency: 'cordova',
        installed: cordovaVersion,
        required: requirement
    };
}

function getPluginRequirement (requirement) {
    return {
        dependency: 'ca.filmaj.AndroidPlugin',
        installed: '4.2.0',
        required: requirement
    };
}

describe('plugin fetching version selection', () => {
    let project, testPlugin;

    beforeEach(() => {
        unmetRequirementsCollector.store = [];

        // We generate warnings when we don't fetch latest. Collect them to make sure we
        // are making the correct warnings
        events.on('warn', unmetRequirementsCollector);

        testPlugin = {
            version: '2.3.0',
            name: 'test-plugin',
            engines: { cordovaDependencies: {} },
            versions: [
                '0.0.2',
                '0.7.0',
                '1.0.0',
                '1.1.0',
                '1.1.3',
                '1.3.0',
                '1.7.0',
                '1.7.1',
                '2.0.0-rc.1',
                '2.0.0-rc.2',
                '2.0.0',
                '2.3.0'
            ]
        };

        spyOn(pluginUtil, 'getInstalledPlugins').and.returnValue([
            { id: 'ca.filmaj.AndroidPlugin', version: '4.2.0' }
        ]);
        spyOn(cordovaUtil, 'getInstalledPlatformsWithVersions').and.returnValue(
            Promise.resolve({ android: '3.1.0' })
        );
    });

    afterEach(() => {
        events.removeListener('warn', unmetRequirementsCollector);
    });

    function getFetchVersion (plugin) {
        return pluginAdd.getFetchVersion(project, plugin, cordovaVersion);
    }

    it('Test 001 : should handle a mix of upper bounds and single versions', () => {
        testPlugin.engines.cordovaDependencies = {
            '0.0.0': { 'cordova-android': '1.0.0' },
            '0.0.2': { 'cordova-android': '>1.0.0' },
            '<1.0.0': { 'cordova-android': '<2.0.0' },
            '1.0.0': { 'cordova-android': '>2.0.0' },
            '1.7.0': { 'cordova-android': '>4.0.0' },
            '<2.3.0': { 'cordova-android': '<6.1.1' },
            '2.3.0': { 'cordova-android': '6.1.1' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('1.3.0');
            expectUnmetRequirements([getPlatformRequirement('6.1.1')]);
        });
    });

    it('Test 002 : should apply upper bound engine constraints when there are no unspecified constraints above the upper bound', () => {
        testPlugin.engines.cordovaDependencies = {
            '1.0.0': { 'cordova-android': '>2.0.0' },
            '1.7.0': { 'cordova-android': '>4.0.0' },
            '<2.3.0': {
                'cordova-android': '<6.1.1',
                'ca.filmaj.AndroidPlugin': '<1.0.0'
            },
            '2.3.0': { 'cordova-android': '6.1.1' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe(null);
            expectUnmetRequirements([getPlatformRequirement('6.1.1')]);
        });
    });

    it('Test 003 : should apply upper bound engine constraints when there are unspecified constraints above the upper bound', () => {
        testPlugin.engines.cordovaDependencies = {
            '0.0.0': {},
            '2.0.0': { 'cordova-android': '~5.0.0' },
            '<1.0.0': { 'cordova-android': '>5.0.0' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('1.7.1');
            expectUnmetRequirements([getPlatformRequirement('~5.0.0')]);
        });
    });

    it('Test 004 : should handle the case where there are no constraints for earliest releases', () => {
        testPlugin.engines.cordovaDependencies = {
            '1.0.0': { 'cordova-android': '~5.0.0' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('0.7.0');
            expectUnmetRequirements([getPlatformRequirement('~5.0.0')]);
        });
    });

    it('Test 005 : should handle the case where the lowest version is unsatisfied', () => {
        testPlugin.engines.cordovaDependencies = {
            '0.0.2': { 'cordova-android': '~5.0.0' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe(null);
            expectUnmetRequirements([getPlatformRequirement('~5.0.0')]);
        });
    });

    it('Test 006 : should handle upperbounds if no single version constraints are given', () => {
        testPlugin.engines.cordovaDependencies = {
            '<1.0.0': { 'cordova-android': '<2.0.0' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('2.3.0');
            expectUnmetRequirements([]);
        });
    });

    it('Test 007 : should apply upper bounds greater than highest version', () => {
        testPlugin.engines.cordovaDependencies = {
            '0.0.0': {},
            '<5.0.0': { 'cordova-android': '<2.0.0' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe(null);
            expectUnmetRequirements([getPlatformRequirement('<2.0.0')]);
        });
    });

    it('Test 008 : should treat empty constraints as satisfied', () => {
        testPlugin.engines.cordovaDependencies = {
            '1.0.0': {},
            '1.1.0': { 'cordova-android': '>5.0.0' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('1.0.0');
            expectUnmetRequirements([getPlatformRequirement('>5.0.0')]);
        });
    });

    it('Test 009 : should ignore an empty cordovaDependencies entry', () => {
        testPlugin.engines.cordovaDependencies = {};

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe(null);
            expectUnmetRequirements([]);
        });
    });

    it('Test 010 : should ignore a badly formatted semver range', () => {
        testPlugin.engines.cordovaDependencies = {
            '1.1.3': { 'cordova-android': 'badSemverRange' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('2.3.0');
            expectUnmetRequirements([]);
        });
    });

    it('Test 011 : should respect unreleased versions in constraints', () => {
        testPlugin.engines.cordovaDependencies = {
            '1.0.0': { 'cordova-android': '3.1.0' },
            '1.1.2': { 'cordova-android': '6.1.1' },
            '1.3.0': { 'cordova-android': '6.1.1' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('1.1.0');
            expectUnmetRequirements([getPlatformRequirement('6.1.1')]);
        });
    });

    it('Test 012 : should respect plugin constraints', () => {
        testPlugin.engines.cordovaDependencies = {
            '0.0.0': { 'ca.filmaj.AndroidPlugin': '1.2.0' },
            '1.1.3': { 'ca.filmaj.AndroidPlugin': '<5.0.0 || >2.3.0' },
            '2.3.0': { 'ca.filmaj.AndroidPlugin': '6.1.1' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('2.0.0');
            expectUnmetRequirements([getPluginRequirement('6.1.1')]);
        });
    });

    it('Test 013 : should respect cordova constraints', () => {
        testPlugin.engines.cordovaDependencies = {
            '0.0.0': { cordova: '>1.0.0' },
            '1.1.3': { cordova: '<3.0.0 || >4.0.0' },
            '2.3.0': { cordova: '6.1.1' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('1.1.0');
            expectUnmetRequirements([getCordovaRequirement('6.1.1')]);
        });
    });

    it('Test 014 : should not include pre-release versions', () => {
        testPlugin.engines.cordovaDependencies = {
            '0.0.0': {},
            '2.0.0': { 'cordova-android': '>5.0.0' }
        };

        // Should not return 2.0.0-rc.2
        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('1.7.1');
            expectUnmetRequirements([getPlatformRequirement('>5.0.0')]);
        });
    });

    it('Test 015 : should not fail if there is no engine in the npm info', () => {
        delete testPlugin.engines;

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe(null);
            expectUnmetRequirements([]);
        });
    });

    it('Test 016 : should not fail if there is no cordovaDependencies in the engines', () => {
        testPlugin.engines = {
            node: '>7.0.0',
            npm: '~2.0.0'
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe(null);
            expectUnmetRequirements([]);
        });
    });

    it('Test 017 : should handle extra whitespace', () => {
        testPlugin.engines.cordovaDependencies = {
            '  1.0.0    ': {},
            '2.0.0   ': { ' cordova-android': '~5.0.0   ' },
            ' <  1.0.0\t': { ' cordova-android  ': ' > 5.0.0' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('1.7.1');
            expectUnmetRequirements([getPlatformRequirement('~5.0.0')]);
        });
    });

    it('Test 018 : should ignore badly typed version requirement entries', () => {
        testPlugin.engines.cordovaDependencies = {
            '1.1.0': ['cordova', '5.0.0'],
            '1.3.0': undefined,
            '1.7.0': null
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('2.3.0');
            expectUnmetRequirements([]);
        });
    });

    it('Test 019 : should ignore badly typed constraint entries', () => {
        testPlugin.engines.cordovaDependencies = {
            '0.0.2': { cordova: 1 },
            '0.7.0': { cordova: {} },
            '1.0.0': { cordova: undefined },
            '1.1.3': { 8: '5.0.0' },
            '1.3.0': { cordova: [] },
            '1.7.1': { cordova: null }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('2.3.0');
            expectUnmetRequirements([]);
        });
    });

    it('Test 020 : should ignore bad semver versions', () => {
        testPlugin.engines.cordovaDependencies = {
            '0.0.0': { 'cordova-android': '5.0.0' },
            notAVersion: { 'cordova-android': '3.1.0' },
            '^1.1.2': { 'cordova-android': '3.1.0' },
            '<=1.3.0': { 'cordova-android': '3.1.0' },
            '1.0': { 'cordova-android': '3.1.0' },
            2: { 'cordova-android': '3.1.0' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe(null);
            expectUnmetRequirements([getPlatformRequirement('5.0.0')]);
        });
    });

    it('Test 021 : should not fail if there are bad semver versions', () => {
        testPlugin.engines.cordovaDependencies = {
            notAVersion: { 'cordova-android': '3.1.0' },
            '^1.1.2': { 'cordova-android': '3.1.0' },
            '<=1.3.0': { 'cordova-android': '3.1.0' },
            '1.0.0': { 'cordova-android': '~3' }, // Good semver
            '2.0.0': { 'cordova-android': '5.1.0' }, // Good semver
            '1.0': { 'cordova-android': '3.1.0' },
            2: { 'cordova-android': '3.1.0' }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('1.7.1');
            expectUnmetRequirements([getPlatformRequirement('5.1.0')]);
        });
    });

    it('Test 022 : should properly warn about multiple unmet requirements', () => {
        testPlugin.engines.cordovaDependencies = {
            '1.7.0': {
                'cordova-android': '>5.1.0',
                'ca.filmaj.AndroidPlugin': '3.1.0',
                cordova: '3.4.2'
            }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('1.3.0');
            expectUnmetRequirements([
                getPlatformRequirement('>5.1.0'),
                getPluginRequirement('3.1.0')
            ]);
        });
    });

    it('Test 023 : should properly warn about both unmet latest and upper bound requirements', () => {
        testPlugin.engines.cordovaDependencies = {
            '1.7.0': { 'cordova-android': '>5.1.0' },
            '<5.0.0': {
                'cordova-android': '>7.1.0',
                'ca.filmaj.AndroidPlugin': '3.1.0'
            }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe(null);
            expectUnmetRequirements([
                getPlatformRequirement('>5.1.0 AND >7.1.0'),
                getPluginRequirement('3.1.0')
            ]);
        });
    });

    it('Test 024 : should not warn about versions past latest', () => {
        testPlugin.engines.cordovaDependencies = {
            '1.7.0': { 'cordova-android': '>5.1.0' },
            '7.0.0': {
                'cordova-android': '>7.1.0',
                'ca.filmaj.AndroidPlugin': '3.1.0'
            }
        };

        return getFetchVersion(testPlugin).then(version => {
            expect(version).toBe('1.3.0');
            expectUnmetRequirements([getPlatformRequirement('>5.1.0')]);
        });
    });
});
