'use strict';
var modelMaker = require('pd-redis-base-record');
var parentizer = require('../');
var anno = require('pd-api-test-anno')();
var childizer = require('../lib/childize');
var q = require('q');
var announcer = require('pd-api-announcer');
var eReport = require('./report-error');
var expect = require('chai').expect;

var Message = modelMaker('message');
var Reply = modelMaker('reply');
var Author = modelMaker('author');
childizer(Reply, Message);
childizer(Author, Message);
parentizer(Message, Reply);
parentizer(Message, Author);

describe('Childize', function () {
    var msgToDelete = [];
    var replToDelete = [];
    var authToDelete = [];
    var newMessageId;
    var newReplyId;
    var newAuthId;
    var MomOfReply;
    var MomOfAuthor;
    before(function (done) {
        anno.init(function () {
            return Message.create({
                content: 'hello world'
            }).then(function (sid) {
                msgToDelete.push(newMessageId = sid);
                MomOfReply = Message.replyOwner(sid);
                return MomOfReply.bear({
                    content: 'hello world again..'
                });
            }).then(function (sid) {
                replToDelete.push(newReplyId = sid);
                MomOfAuthor = Message.authorOwner(newMessageId);
                return MomOfAuthor.bear({
                    name: 'johndoe'
                });
            }).then(function (sid) {
                authToDelete.push(newAuthId = sid);
            }).fail(function (err) {
                eReport(err);
            });
        }, done, 'Childize');
    });

    it('should abandon parent', function (done) {
        anno.tcase(function () {
            return Reply.messageKid(newReplyId).abandon(newMessageId)
                .then(function () {
                    return MomOfReply.hasKid(newReplyId);
                }).then(function () {
                    throw new Error('failed to abandon parent!');
                }).fail(function (err) {
                    announcer.assertSysErrorFor(err, 'reply', 'gone');
                    console.log('found replationship set cleared..');
                    return Reply.findBySid(newReplyId, {
                        fields: ['messageSid']
                    });
                }).then(function (fields) {
                    expect(fields[0]).to.equal(null);
                    console.log('found child link field cleared..');
                    return MomOfAuthor.hasKid(newAuthId);
                }).then(function () {
                    console.log('Author relationship retained..');
                    return Author.findBySid(newAuthId, {
                        fields: ['messageSid']
                    });
                }).then(function (field) {
                    expect(field[0]).to.equal(newMessageId + '');
                    console.log('Author link data retained..');
                }).fail(function (err) {
                    eReport(err);
                });
        }, done, 'abandon parent');
    });

    it('should be-kid a parent', function (done) {
        anno.tcase(function () {
            return Reply.messageKid(newReplyId).beKidOf(newMessageId).then(function () {
                console.log('beKid executed..');
                return MomOfReply.hasKid(newReplyId);
            }).then(function () {
                console.log('found parenthood rebuilt..');
                return Reply.findBySid(newReplyId, {
                    fields: ['messageSid']
                });
            }).then(function (replyRec) {
                expect(replyRec[0]).to.equal(newMessageId + '');
                console.log('found parenthood data link..');
                return Reply.messageKid(newReplyId).beKidOf(newMessageId);
            }).fail(function (err) {
                announcer.assertSysErrorFor(err, 'reply', 'already-adopted');
                console.log('stopped duplicate be-kid request..');
                return Reply.messageKid(newReplyId).getParent({
                    withCreatedAt: true
                });
            }).then(function (rec) {
                expect(rec['pd-sid']).to.equal(newMessageId + '');
                console.log('Used getParent() to have found its parent..');
                console.log(rec);
                return Reply.messageKid(newReplyId).getParent({
                    fields: ['content']
                });
            }).then(function (rec) {
                expect(rec[0]).to.equal('hello world');
                console.log('Used getParent() to have found its parent..');
                console.log(rec);
            }).fail(function (err) {
                eReport(err);
            });
        }, done, 'bekid parent');
    });

    after(function (done) {
        anno.fin(function () {
            var promises = [];
            replToDelete.forEach(function (sid) {
                promises.push(
                    Reply.remove(sid, function (multis) {
                        console.log(multis);
                        expect(multis.length).to.equal(3);
                        return multis;
                    }).fail(function (err) {
                        eReport(err);
                    })
                );
            });
            authToDelete.forEach(function (sid) {
                promises.push(
                    Author.remove(sid).fail(function (err) {
                        eReport(err);
                    })
                );
            });
            return q.allSettled(promises).then(function () {
                var promises = [];
                console.log('msgToDelete:');
                console.log(msgToDelete);
                msgToDelete.forEach(function (sid) {
                    promises.push(
                        Message.remove(sid, function (multis) {
                            console.log(multis);
                            expect(multis.length).to.equal(2);
                            return multis;
                        }).fail(function (err) {
                            eReport(err);
                        }).then(function () {
                            return Message.clearSidCounter().fail(function (err) {
                                eReport(err);
                            });
                        })
                    );
                    promises.push(
                        Reply.clearSidCounter().fail(function (err) {
                            eReport(err);
                        })
                    );
                    promises.push(
                        Author.clearSidCounter().fail(function (err) {
                            eReport(err);
                        })
                    );
                });
                return q.allSettled(promises);
            });
        }, done, 'Childize');
    });
});
