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

// global to store a contact so it doesn't have to be created or retrieved multiple times
// all of the setup/teardown test methods can reference the following variables to make sure to do the right cleanup
var gContactObj = null;
var gContactId = null;

var removeContact = function(){
    if (gContactObj) {
        gContactObj.remove(function(){},function(){
            console.log("[CONTACTS ERROR]: removeContact cleanup method failed to clean up test artifacts.");
        });
        gContactObj = null;
    }
};

describe("Contacts (navigator.contacts)", function () {
    it("should exist", function() {
        expect(navigator.contacts).toBeDefined();
    });

    it("should contain a find function", function() {
        expect(navigator.contacts.find).toBeDefined();
        expect(typeof navigator.contacts.find).toBe('function');
    });

    describe("find method", function() {
        it("success callback should be called with an array", function() {
            var win = jasmine.createSpy().andCallFake(function(result) {
                    expect(result).toBeDefined();
                    expect(result instanceof Array).toBe(true);
                }),
                fail = jasmine.createSpy(),
                obj = new ContactFindOptions();

            runs(function () {
                obj.filter="";
                obj.multiple=true;
                navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], win, fail, obj);
            });

            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);

            runs(function () {
                expect(fail).not.toHaveBeenCalled();
            });
        });

        it("should throw an exception if success callback is empty", function() {
            var fail = function() {};
            var obj = new ContactFindOptions();
            obj.filter="";
            obj.multiple=true;

            expect(function () {
                navigator.contacts.find(["displayName", "name", "emails", "phoneNumbers"], null, fail, obj);
            }).toThrow();
        });

        it("error callback should be called when no fields are specified", function() {
            var win = jasmine.createSpy(),
                fail = jasmine.createSpy(function(result) {
                    expect(result).toBeDefined();
                    expect(result.code).toBe(ContactError.INVALID_ARGUMENT_ERROR);
                }),
                obj = new ContactFindOptions();

            runs(function () {
                obj.filter="";
                obj.multiple=true;
                navigator.contacts.find([], win, fail, obj);
            });

            waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT);

            runs(function () {
                expect(win).not.toHaveBeenCalled();
                expect(fail).toHaveBeenCalled();
            });
        });

        describe("with newly-created contact", function () {

            afterEach(removeContact);

            it("should be able to find a contact by name", function() {
                var foundName = jasmine.createSpy().andCallFake(function(result) {
                        var bFound = false;
                        try {
                            for (var i=0; i < result.length; i++) {
                                if (result[i].name.familyName == "Delete") {
                                    bFound = true;
                                    break;
                                }
                            }
                        } catch(e) {
                            return false;
                        }
                        return bFound;
                    }),
                    fail = jasmine.createSpy(),
                    test = jasmine.createSpy().andCallFake(function(savedContact) {
                        console.log('in test');
                        // update so contact will get removed
                        gContactObj = savedContact;
                        // ----
                        // Find asserts
                        // ---
                        var findWin = jasmine.createSpy().andCallFake(function(object) {
                                console.log('in findwin');
                                expect(object instanceof Array).toBe(true);
                                expect(object.length >= 1).toBe(true);
                                expect(foundName(object)).toBe(true);
                            }),
                            findFail = jasmine.createSpy(),
                            obj = new ContactFindOptions();

                        obj.filter="Delete";
                        obj.multiple=true;

                        runs(function () {
                            navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, findFail, obj);
                        });

                        waitsFor(function () { return foundName.wasCalled; }, "foundName not done", Tests.TEST_TIMEOUT);

                        runs(function () {
                            expect(findFail).not.toHaveBeenCalled();
                            expect(fail).not.toHaveBeenCalled();
                        });
                    });

                runs(function () {
                    gContactObj = new Contact();
                    gContactObj.name = new ContactName();
                    gContactObj.name.familyName = "Delete";
                    gContactObj.save(test, fail);
                });

                waitsFor(function () { return test.wasCalled; }, "test not done", Tests.TEST_TIMEOUT);
            });
        });
    });

    describe('create method', function() {

        it("should exist", function() {
            expect(navigator.contacts.create).toBeDefined();
            expect(typeof navigator.contacts.create).toBe('function');
        });

        it("should return a Contact object", function() {
            var bDay = new Date(1976, 7,4);
            var obj = navigator.contacts.create({"displayName": "test name", "gender": "male", "note": "my note", "name": {"formatted": "Mr. Test Name"}, "emails": [{"value": "here@there.com"}, {"value": "there@here.com"}], "birthday": bDay});

            expect(obj).toBeDefined();
            expect(obj.displayName).toBe('test name');
            expect(obj.note).toBe('my note');
            expect(obj.name.formatted).toBe('Mr. Test Name');
            expect(obj.emails.length).toBe(2);
            expect(obj.emails[0].value).toBe('here@there.com');
            expect(obj.emails[1].value).toBe('there@here.com');
            expect(obj.nickname).toBe(null);
            expect(obj.birthday).toBe(bDay);
        });
    });

    describe("Contact object", function () {
        it("should be able to create instance", function() {
            var contact = new Contact("a", "b", new ContactName("a", "b", "c", "d", "e", "f"), "c", [], [], [], [], [], "f", "i",
                [], [], []);
            expect(contact).toBeDefined();
            expect(contact.id).toBe("a");
            expect(contact.displayName).toBe("b");
            expect(contact.name.formatted).toBe("a");
            expect(contact.nickname).toBe("c");
            expect(contact.phoneNumbers).toBeDefined();
            expect(contact.emails).toBeDefined();
            expect(contact.addresses).toBeDefined();
            expect(contact.ims).toBeDefined();
            expect(contact.organizations).toBeDefined();
            expect(contact.birthday).toBe("f");
            expect(contact.note).toBe("i");
            expect(contact.photos).toBeDefined();
            expect(contact.categories).toBeDefined();
            expect(contact.urls).toBeDefined();
        });

        it("should be able to define a ContactName object", function() {
            var contactName = new ContactName("Dr. First Last Jr.", "Last", "First", "Middle", "Dr.", "Jr.");
            expect(contactName).toBeDefined();
            expect(contactName.formatted).toBe("Dr. First Last Jr.");
            expect(contactName.familyName).toBe("Last");
            expect(contactName.givenName).toBe("First");
            expect(contactName.middleName).toBe("Middle");
            expect(contactName.honorificPrefix).toBe("Dr.");
            expect(contactName.honorificSuffix).toBe("Jr.");
        });

        it("should be able to define a ContactField object", function() {
            var contactField = new ContactField("home", "8005551212", true);
            expect(contactField).toBeDefined();
            expect(contactField.type).toBe("home");
            expect(contactField.value).toBe("8005551212");
            expect(contactField.pref).toBe(true);
        });

        it("ContactField object should coerce type and value properties to strings", function() {
            var contactField = new ContactField(12345678, 12345678, true);
            expect(contactField.type).toBe("12345678");
            expect(contactField.value).toBe("12345678");
        });

        it("should be able to define a ContactAddress object", function() {
            var contactAddress = new ContactAddress(true, "home", "a","b","c","d","e","f");
            expect(contactAddress).toBeDefined();
            expect(contactAddress.pref).toBe(true);
            expect(contactAddress.type).toBe("home");
            expect(contactAddress.formatted).toBe("a");
            expect(contactAddress.streetAddress).toBe("b");
            expect(contactAddress.locality).toBe("c");
            expect(contactAddress.region).toBe("d");
            expect(contactAddress.postalCode).toBe("e");
            expect(contactAddress.country).toBe("f");
        });

        it("should be able to define a ContactOrganization object", function() {
            var contactOrg = new ContactOrganization(true, "home", "a","b","c","d","e","f","g");
            expect(contactOrg).toBeDefined();
            expect(contactOrg.pref).toBe(true);
            expect(contactOrg.type).toBe("home");
            expect(contactOrg.name).toBe("a");
            expect(contactOrg.department).toBe("b");
            expect(contactOrg.title).toBe("c");
        });

        it("should be able to define a ContactFindOptions object", function() {
            var contactFindOptions = new ContactFindOptions("a", true, "b");
            expect(contactFindOptions).toBeDefined();
            expect(contactFindOptions.filter).toBe("a");
            expect(contactFindOptions.multiple).toBe(true);
        });

        it("should contain a clone function", function() {
            var contact = new Contact();
            expect(contact.clone).toBeDefined();
            expect(typeof contact.clone).toBe('function');
        });

        it("clone function should make deep copy of Contact Object", function() {
            var contact = new Contact();
            contact.id=1;
            contact.displayName="Test Name";
            contact.nickname="Testy";
            contact.gender="male";
            contact.note="note to be cloned";
            contact.name = new ContactName("Mr. Test Name");

            var clonedContact = contact.clone();

            expect(contact.id).toBe(1);
            expect(clonedContact.id).toBe(null);
            expect(clonedContact.displayName).toBe(contact.displayName);
            expect(clonedContact.nickname).toBe(contact.nickname);
            expect(clonedContact.gender).toBe(contact.gender);
            expect(clonedContact.note).toBe(contact.note);
            expect(clonedContact.name.formatted).toBe(contact.name.formatted);
            expect(clonedContact.connected).toBe(contact.connected);
        });

        it("should contain a save function", function() {
            var contact = new Contact();
            expect(contact.save).toBeDefined();
            expect(typeof contact.save).toBe('function');
        });

        it("should contain a remove function", function() {
            var contact = new Contact();
            expect(contact.remove).toBeDefined();
            expect(typeof contact.remove).toBe('function');
        });
    });

    describe('save method', function () {
        it("should be able to save a contact", function() {
            var bDay = new Date(1976, 6,4);
            gContactObj = navigator.contacts.create({"gender": "male", "note": "my note", "name": {"familyName": "Delete", "givenName": "Test"}, "emails": [{"value": "here@there.com"}, {"value": "there@here.com"}], "birthday": bDay});

            var saveSuccess = jasmine.createSpy().andCallFake(function(obj) {
                    expect(obj).toBeDefined();
                    expect(obj.note).toBe('my note');
                    expect(obj.name.familyName).toBe('Delete');
                    expect(obj.name.givenName).toBe('Test');
                    expect(obj.emails.length).toBe(2);
                    expect(obj.emails[0].value).toBe('here@there.com');
                    expect(obj.emails[1].value).toBe('there@here.com');
                    expect(obj.birthday.toDateString()).toBe(bDay.toDateString());
                    expect(obj.addresses).toBe(null);
                    // must store returned object in order to have id for update test below
                    gContactObj = obj;
                }),
                saveFail = jasmine.createSpy();

            runs(function () {
                gContactObj.save(saveSuccess, saveFail);
            });

            waitsFor(function () { return saveSuccess.wasCalled; }, "saveSuccess never called", Tests.TEST_TIMEOUT);

            runs(function () {
                expect(saveFail).not.toHaveBeenCalled();
            });
         });
        // HACK: there is a reliance between the previous and next test. This is bad form.
        it("update a contact", function() {
            expect(gContactObj).toBeDefined();

            var bDay = new Date(1975, 5,4);
            var noteText = "an UPDATED note";

            var win = jasmine.createSpy().andCallFake(function(obj) {
                    expect(obj).toBeDefined();
                    expect(obj.id).toBe(gContactObj.id);
                    expect(obj.note).toBe(noteText);
                    expect(obj.birthday.toDateString()).toBe(bDay.toDateString());
                    expect(obj.emails.length).toBe(1);
                    expect(obj.emails[0].value).toBe('here@there.com');
                    removeContact();         // Clean up contact object
                }), fail = jasmine.createSpy().andCallFake(removeContact);

            runs(function () {
                // remove an email
                gContactObj.emails[1].value = "";
                // change birthday
                gContactObj.birthday = bDay;
                // update note
                gContactObj.note = noteText;
                gContactObj.save(win, fail);
            });

            waitsFor(function () { return win.wasCalled; }, "saveSuccess never called", Tests.TEST_TIMEOUT);

            runs(function () {
                expect(fail).not.toHaveBeenCalled();
            });
        });
    });

    describe('Contact.remove method', function () {
        afterEach(removeContact);

        it("calling remove on a contact has an id of null should return ContactError.UNKNOWN_ERROR", function() {
            var win = jasmine.createSpy();
            var fail = jasmine.createSpy().andCallFake(function(result) {
                expect(result.code).toBe(ContactError.UNKNOWN_ERROR);
            });

            runs(function () {
                var rmContact = new Contact();
                rmContact.remove(win, fail);
            });

            waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT);

            runs(function () {
                expect(win).not.toHaveBeenCalled();
            });
        });

        it("calling remove on a contact that does not exist should return ContactError.UNKNOWN_ERROR", function() {
            var win = jasmine.createSpy();
            var fail = jasmine.createSpy().andCallFake(function(result) {
                expect(result.code).toBe(ContactError.UNKNOWN_ERROR);
            });

            runs(function () {
                var rmContact = new Contact();
                // this is a bit risky as some devices may have contact ids that large
                var contact = new Contact("this string is supposed to be a unique identifier that will never show up on a device");
                contact.remove(win, fail);
            });

            waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT);

            runs(function () {
                expect(win).not.toHaveBeenCalled();
            });
        });
    });

    describe("Round trip Contact tests (creating + save + delete + find).", function () {
        afterEach(removeContact);

        it("Creating, saving, finding a contact should work, removing it should work, after which we should not be able to find it, and we should not be able to delete it again.", function() {
            var done = false;
            runs(function () {
                gContactObj = new Contact();
                gContactObj.name = new ContactName();
                gContactObj.name.familyName = "DeleteMe";
                gContactObj.save(function(c_obj) {
                    var findWin = function(cs) {
                        expect(cs.length).toBe(1);
                        // update to have proper saved id
                        gContactObj = cs[0];
                        gContactObj.remove(function() {
                            var findWinAgain = function(seas) {
                                expect(seas.length).toBe(0);
                                gContactObj.remove(function() {
                                    throw("success callback called after non-existent Contact object called remove(). Test failed.");
                                }, function(e) {
                                    expect(e.code).toBe(ContactError.UNKNOWN_ERROR);
                                    done = true;
                                });
                            };
                            var findFailAgain = function(e) {
                                throw("find error callback invoked after delete, test failed.");
                            };
                            var obj = new ContactFindOptions();
                            obj.filter="DeleteMe";
                            obj.multiple=true;
                            navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWinAgain, findFailAgain, obj);
                        }, function(e) {
                            throw("Newly created contact's remove function invoked error callback. Test failed.");
                        });
                    };
                    var findFail = function(e) {
                        throw("Failure callback invoked in navigator.contacts.find call, test failed.");
                    };
                    var obj = new ContactFindOptions();
                    obj.filter="DeleteMe";
                    obj.multiple=true;
                    navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, findFail, obj);
                }, function(e) {
                    throw("Contact creation failed, error callback was invoked.");
                });
            });

            waitsFor(function () { return done; }, Tests.TEST_TIMEOUT);
        });
    });

    describe('ContactError interface', function () {
        it("ContactError constants should be defined", function() {
            expect(ContactError.UNKNOWN_ERROR).toBe(0);
            expect(ContactError.INVALID_ARGUMENT_ERROR).toBe(1);
            expect(ContactError.TIMEOUT_ERROR).toBe(2);
            expect(ContactError.PENDING_OPERATION_ERROR).toBe(3);
            expect(ContactError.IO_ERROR).toBe(4);
            expect(ContactError.NOT_SUPPORTED_ERROR).toBe(5);
            expect(ContactError.PERMISSION_DENIED_ERROR).toBe(20);
        });
    });
});
