/**
 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.
 */
var platforms = require('../../platforms'),
    util = require('../../src/util'),
    path = require('path'),
    shell = require('shelljs'),
    plist = require('plist'),
    xcode = require('xcode'),
    ET = require('elementtree'),
    fs = require('fs'),
    config = require('../../src/config'),
    config_parser = require('../../src/config_parser'),
    cordova = require('../../cordova');

describe('ios project parser', function () {
    var proj = '/some/path';
    var exec, custom, readdir, cfg_parser;
    beforeEach(function() {
        exec = spyOn(shell, 'exec').andCallFake(function(cmd, opts, cb) {
            cb(0, '');
        });
        custom = spyOn(config, 'has_custom_path').andReturn(false);
        readdir = spyOn(fs, 'readdirSync').andReturn(['test.xcodeproj']);
        cfg_parser = spyOn(util, 'config_parser');
    });
    describe('constructions', function() {
        it('should throw if provided directory does not contain an xcodeproj file', function() {
            readdir.andReturn(['noxcodehere']);
            expect(function() {
                new platforms.ios.parser(proj);
            }).toThrow('The provided path is not a Cordova iOS project.');
        });
        it('should create an instance with path, pbxproj, xcodeproj, originalName and cordovaproj properties', function() {
            expect(function() {
                var p = new platforms.ios.parser(proj);
                expect(p.path).toEqual(proj);
                expect(p.pbxproj).toEqual(path.join(proj, 'test.xcodeproj', 'project.pbxproj'));
                expect(p.xcodeproj).toEqual(path.join(proj, 'test.xcodeproj'));
                expect(p.originalName).toEqual('/test');
            }).not.toThrow();
        });
    });
    describe('check_requirements', function() {
        it('should fire a callback if there is an error during shelling out', function(done) {
            exec.andCallFake(function(cmd, opts, cb) {
                cb(50, 'there was an errorz!');
            });
            platforms.ios.parser.check_requirements(proj, function(err) {
                expect(err).toContain('there was an errorz!');
                done();
            });
        });
        it('should fire a callback if the xcodebuild version is less than 4.5.x', function(done) {
            exec.andCallFake(function(cmd, opts, cb) {
                cb(0, 'version 4.4.9');
            });
            platforms.ios.parser.check_requirements(proj, function(err) {
                expect(err).toEqual('Xcode version installed is too old. Minimum: >=4.5.x, yours: 4.4.9');
                done();
            });
        });
        it('should not return an error if the xcodebuild version 2 digits and not proper semver (eg: 5.0), but still satisfies the MIN_XCODE_VERSION', function(done) {
            exec.andCallFake(function(cmd, opts, cb) {
                cb(0, 'version 5.0');
            });
            platforms.ios.parser.check_requirements(proj, function(err) {
                expect(err).toBe(false);
                done();
            });
        });
    });

    describe('instance', function() {
        var p, cp, rm, is_cordova, write, read;
        var ios_proj = path.join(proj, 'platforms', 'ios');
        beforeEach(function() {
            p = new platforms.ios.parser(ios_proj);
            cp = spyOn(shell, 'cp');
            rm = spyOn(shell, 'rm');
            is_cordova = spyOn(util, 'isCordova').andReturn(proj);
            write = spyOn(fs, 'writeFileSync');
            read = spyOn(fs, 'readFileSync');
        });

        describe('update_from_config method', function() {
            var et, xml, find, write_xml, root;
            var cfg, find_obj, root_obj, cfg_access_add, cfg_access_rm, cfg_pref_add, cfg_pref_rm;
            var plist_parse, plist_build, xc;
            var update_name, xc_write;
            beforeEach(function() {
                find_obj = {
                    text:'hi'
                };
                root_obj = {
                    attrib:{
                        package:'android_pkg'
                    }
                };
                find = jasmine.createSpy('ElementTree find').andReturn(find_obj);
                write_xml = jasmine.createSpy('ElementTree write');
                root = jasmine.createSpy('ElementTree getroot').andReturn(root_obj);
                et = spyOn(ET, 'ElementTree').andReturn({
                    find:find,
                    write:write_xml,
                    getroot:root
                });
                xml = spyOn(ET, 'XML');
                plist_parse = spyOn(plist, 'parseFileSync').andReturn({
                });
                plist_build = spyOn(plist, 'build').andReturn('');
                update_name = jasmine.createSpy('update_name');
                xc_write = jasmine.createSpy('xcode writeSync');
                xc = spyOn(xcode, 'project').andReturn({
                    parse:function(cb) {cb();},
                    updateProductName:update_name,
                    writeSync:xc_write
                });
                cfg = new config_parser();
                cfg.name = function() { return 'testname' };
                cfg.packageName = function() { return 'testpkg' };
                cfg.version = function() { return 'one point oh' };
                cfg.access.get = function() { return [] };
                cfg.preference.get = function() { return [] };
                cfg_access_add = jasmine.createSpy('config_parser access add');
                cfg_access_rm = jasmine.createSpy('config_parser access rm');
                cfg_pref_rm = jasmine.createSpy('config_parser pref rm');
                cfg_pref_add = jasmine.createSpy('config_parser pref add');
                cfg_parser.andReturn({
                    access:{
                        remove:cfg_access_rm,
                        get:function(){},
                        add:cfg_access_add
                    },
                    preference:{
                        remove:cfg_pref_rm,
                        get:function(){},
                        add:cfg_pref_add
                    }
                });
                p = new platforms.ios.parser(ios_proj);
            });

            it('should write out the app name to pbxproj by calling xcode.updateProductName', function(done) {
                p.update_from_config(cfg, function() {
                    expect(update_name).toHaveBeenCalledWith('testname');
                    done();
                });
            });
            it('should write out the app id to info plist as CFBundleIdentifier', function(done) {
                p.update_from_config(cfg, function() {
                    expect(plist_build.mostRecentCall.args[0].CFBundleIdentifier).toEqual('testpkg');
                    done();
                });
            });
            it('should write out the app version to info plist as CFBundleVersion', function(done) {
                p.update_from_config(cfg, function() {
                    expect(plist_build.mostRecentCall.args[0].CFBundleVersion).toEqual('one point oh');
                    done();
                });
            });
            it('should wipe out the ios whitelist every time', function(done) {
                p.update_from_config(cfg, function() {
                    expect(cfg_access_rm).toHaveBeenCalled();
                    done();
                });
            });
            it('should update the whitelist', function(done) {
                cfg.access.get = function() { return ['one'] };
                p.update_from_config(cfg, function() {
                    expect(cfg_access_add).toHaveBeenCalledWith('one');
                    done();
                });
            });
            it('should update preferences', function(done) {
                var sample_pref = {name:'pref',value:'yes'};
                cfg.preference.get = function() { return [sample_pref] };
                p.update_from_config(cfg, function() {
                    expect(cfg_pref_add).toHaveBeenCalledWith(sample_pref);
                    done();
                });
            });
            it('should wipe out the ios preferences every time', function(done) {
                p.update_from_config(cfg, function() {
                    expect(cfg_pref_rm).toHaveBeenCalled();
                    done();
                });
            });
            it('should write out default preferences every time', function(done) {
                var sample_pref = {name:'preftwo',value:'false'};
                cfg.preference.get = function() { return [sample_pref] };
                p.update_from_config(cfg, function() {
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"KeyboardDisplayRequiresUserAction",value:"true"});
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"SuppressesIncrementalRendering",value:"false"});
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"UIWebViewBounce",value:"true"});
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"TopActivityIndicator",value:"gray"});
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"EnableLocation",value:"false"});
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"EnableViewportScale",value:"false"});
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"AutoHideSplashScreen",value:"true"});
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"ShowSplashScreenSpinner",value:"true"});
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"MediaPlaybackRequiresUserAction",value:"false"});
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"AllowInlineMediaPlayback",value:"false"});
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"OpenAllWhitelistURLsInWebView",value:"false"});
                    expect(cfg_pref_add).toHaveBeenCalledWith({name:"BackupWebStorage",value:"cloud"});
                    done();
                });
            });
        });
        describe('www_dir method', function() {
            it('should return /www', function() {
                expect(p.www_dir()).toEqual(path.join(ios_proj, 'www'));
            });
        });
        describe('staging_dir method', function() {
            it('should return .staging/www', function() {
                expect(p.staging_dir()).toEqual(path.join(ios_proj, '.staging', 'www'));
            });
        });
        describe('config_xml method', function() {
            it('should return the location of the config.xml', function() {
                expect(p.config_xml()).toEqual(path.join(ios_proj, 'test', 'config.xml'));
            });
        });
        describe('update_www method', function() {
            it('should rm project-level www and cp in platform agnostic www', function() {
                p.update_www();
                expect(rm).toHaveBeenCalled();
                expect(cp).toHaveBeenCalled();
            });
            it('should copy in a fresh cordova.js from stock cordova lib if no custom lib is specified', function() {
                p.update_www();
                expect(cp.mostRecentCall.args[1]).toMatch(util.libDirectory);
            });
            it('should copy in a fresh cordova.js from custom cordova lib if custom lib is specified', function() {
                var custom_path = '/custom/path';
                custom.andReturn(custom_path);
                p.update_www();
                expect(cp.mostRecentCall.args[1]).toMatch(custom_path);
            });
        });
        describe('update_overrides method', function() {
            var exists;
            beforeEach(function() {
                exists = spyOn(fs, 'existsSync').andReturn(true);
            });
            it('should do nothing if merges directory does not exist', function() {
                exists.andReturn(false);
                p.update_overrides();
                expect(cp).not.toHaveBeenCalled();
            });
            it('should copy merges path into www', function() {
                p.update_overrides();
                expect(cp).toHaveBeenCalled();
            });
        });
        describe('update_staging method', function() {
            var exists;
            beforeEach(function() {
                exists = spyOn(fs, 'existsSync').andReturn(true);
            });
            it('should do nothing if staging dir does not exist', function() {
                exists.andReturn(false);
                p.update_staging();
                expect(cp).not.toHaveBeenCalled();
            });
            it('should copy the staging dir into www if staging dir exists', function() {
                p.update_staging();
                expect(cp).toHaveBeenCalled();
            });
        });
        describe('update_project method', function() {
            var config, www, overrides, staging, svn;
            beforeEach(function() {
                config = spyOn(p, 'update_from_config').andCallFake(function(cfg, cb) { cb() });
                www = spyOn(p, 'update_www');
                overrides = spyOn(p, 'update_overrides');
                staging = spyOn(p, 'update_staging');
                svn = spyOn(util, 'deleteSvnFolders');
            });
            it('should call update_from_config', function() {
                p.update_project();
                expect(config).toHaveBeenCalled();
            });
            it('should throw if update_from_config errors', function(done) {
                var err = new Error('uh oh!');
                config.andCallFake(function(cfg, cb) { cb(err); });
                p.update_project({}, function(err) {
                    expect(err).toEqual(err);
                    done();
                });
            });
            it('should call update_www', function(done) {
                p.update_project({}, function() {
                    expect(www).toHaveBeenCalled();
                    done();
                });
            });
            it('should call update_overrides', function() {
                p.update_project();
                expect(overrides).toHaveBeenCalled();
            });
            it('should call update_staging', function() {
                p.update_project();
                expect(staging).toHaveBeenCalled();
            });
            it('should call deleteSvnFolders', function() {
                p.update_project();
                expect(svn).toHaveBeenCalled();
            });
        });
    });
});
