/// <reference path="../typings/tsd.d.ts" />
'use strict'

import * as chai from 'chai';
import * as _ from './helpers';

import {MemoryAdapter} from '../src/adapters/MemoryAdapter';
import {manager} from '../src/manager';

import {data} from './fixtures/data';
import * as models from './fixtures/models';

manager.defineConnection({
  name: 'default',
  adapter: MemoryAdapter
});

const expect = chai.expect;

describe('relations', () => {
  
  beforeEach(done => {
    manager.init().subscribe(connection => {        
      done();
    });
  });
  
  describe('HasMany', () => {
    const book: any = new models.Book({title: 'Title', price: 100});
    const author = new models.Author({name: 'Author'});
    let authorId;
    
    it('find related objects', done => {
      let b;
      author.save()
        .mergeMap(saved => {
          authorId = saved['id'];
          book.author(saved);
          return book.save();
        })
        .mergeMap(saved => {
          b = saved;
          const a = new models.Author({id: authorId});          
          return a.books.find().toArray();
        })
        .mergeMap(books => {
          expect((<any>books).length).to.be.equal(1);
          expect(books[0].toJSON()).to.be.deep.equal(b.toJSON());
          const a = new models.Author({id: authorId});
          return a.books.findById(b.id);
        })
        .subscribe(f => {
          expect((<any>f).toJSON()).to.be.deep.equal(b.toJSON())
        }, _.log, () => done());      
    });
    
    it('delete related objects', done => {
      let book = new models.Book(data[0]);
      let author = new models.Author({name: 'Author name'});
      let authorId;
      author.save()
        .mergeMap(saved => {
          author = <models.Author>saved;          
          return author.books.create(book);
        })
        .mergeMap(book => {
          expect(book['authorId']).to.be.equal(author['id']);
          return author.books.destroyById(book['id']);
        })
        .mergeMap(() => author.books.find().toArray())
        .subscribe(books => {
          expect((<any>books).length).to.be.equal(0);
        }, _.log, () => done());
    });
  });
  
  describe('BelongsTo', () => {
    
    it('set parent object', done => {
      const book: any = new models.Book({title: 'Title', price: 100});
      const author = new models.Author({name: 'Author'});
      let authorId;
      author.save()
        .mergeMap(saved => {
          authorId = saved['id'];
          book.author(author);
          return book.save();
        })
        .subscribe(saved => {
          expect(saved['authorId']).to.be.equal(authorId);
        }, _.log, () => done());      
    });
    
    it('get parent object', done => {
      const book: any = new models.Book({title: 'Title', price: 100});
      const author = new models.Author({name: 'Author'});
      let authorId;
      author.save()
        .mergeMap(saved => {
          book.author(author);
          return book.save();
        })
        .mergeMap(saved => models.Book.findById(saved['id']))
        .mergeMap(b => (<any>b).author())
        .subscribe(a => {
          expect(a['name']).to.be.equal(author.name);
        }, _.log, () => done());      
    });
    
    it('set parent by id', done => {
      const book: any = new models.Book({title: 'Title', price: 100});
      const author = new models.Author({name: 'Author'});
      let authorId;
      author.save()
        .mergeMap(saved => {
          authorId = saved['id'];
          book.authorId = authorId;
          return book.save();
        })
        .mergeMap(b => (<any>b).author())
        .subscribe(a => {
          expect(a['id']).to.be.equal(authorId);
          expect(a['name']).to.be.equal(author.name);
        }, _.log, () => done()); 
    });
    
  });
});