'use strict'

var should = require('should'),
    config = require('../../helpers').config,
    UsergridClient = require('../../lib/client'),
    UsergridEntity = require('../../lib/entity'),
    UsergridUser = require('../../lib/user'),
    UsergridResponseError = require('../../lib/responseError'),
    _ = require('lodash')

var client = new UsergridClient()

var _response

before(function(done) {

    this.slow(1000)
    this.timeout(6000)

    client.GET(config.testCollection, function(err, usergridResponse) {
        _response = usergridResponse
        done()
    })
})

describe('headers', function() {
    it('should be an object', function() {
        _response.headers.should.be.an.Object().with.property('content-type')
    })
})

describe('statusCode', function() {
    it('should be a number', function() {
        _response.statusCode.should.be.a.Number()
    })
})

describe('metadata', function() {
    it('should be a read-only object', function() {
        _response.metadata.should.be.an.Object().with.any.properties(['action', 'application', 'path', 'uri', 'timestamp', 'duration'])
        Object.isFrozen(_response.metadata).should.be.true()
        should(function() {
            _response.metadata.uri = 'TEST'
        }).throw()
    })
})

describe('error', function() {
    it('should be a UsergridResponseError object', function(done) {

        this.slow(1000)
        this.timeout(6000)

        client.GET(config.testCollection, 'BADNAMEORUUID', function(err, usergridResponse) {
            usergridResponse.error.should.be.an.instanceof(UsergridResponseError)
            done()
        })
    })
})

describe('users', function() {

    this.slow(1000)
    this.timeout(6000)

    it('response.users should be an array of UsergridUser objects', function(done) {
        client.setAppAuth(config.clientId, config.clientSecret, config.tokenTtl)
        client.authenticateApp(function(err) {
            should(err).be.null()
            client.GET('users', function(err, usergridResponse) {
                usergridResponse.statusCode.should.equal(200)
                usergridResponse.users.should.be.an.Array()
                usergridResponse.users.forEach(function(user) {
                    user.should.be.an.instanceof(UsergridUser)
                })
                done()
            })
        })
    })
})

describe('user', function() {

    this.slow(1000)
    this.timeout(6000)

    var user

    it('response.user should be a UsergridUser object and have a valid uuid matching the first object in response.users', function(done) {
        client.setAppAuth(config.clientId, config.clientSecret, config.tokenTtl)
        client.authenticateApp(function(err) {
            should(err).be.null()
            client.GET('users', function(err, usergridResponse) {
                user = usergridResponse.user
                user.should.be.an.instanceof(UsergridUser).with.property('uuid').equal(_.first(usergridResponse.entities).uuid)
                done()
            })
        })
    })

    it('response.user should also be a UsergridEntity object', function(done) {
        user.isUser.should.be.true()
        user.should.be.an.instanceof(UsergridEntity)
        done()
    })
})

describe('entities', function() {
    it('should be an array of UsergridEntity objects', function() {
        _response.entities.should.be.an.Array()
        _response.entities.forEach(function(entity) {
            entity.should.be.an.instanceof(UsergridEntity)
        })
    })
})

describe('first, entity', function() {
    it('response.first should be a UsergridEntity object and have a valid uuid matching the first object in response.entities', function() {
        _response.first.should.be.an.instanceof(UsergridEntity).with.property('uuid').equal(_.first(_response.entities).uuid)
    })

    it('response.entity should be a reference to response.first', function() {
        _response.entity.should.deepEqual(_response.first)
    })
})

describe('last', function() {
    it('last should be a UsergridEntity object and have a valid uuid matching the last object in response.entities', function() {
        _response.last.should.be.an.instanceof(UsergridEntity).with.property('uuid').equal(_.last(_response.entities).uuid)
    })
})

describe('hasNextPage', function() {
    this.slow(1000)
    this.timeout(6000)

    it('should be true when more entities exist', function(done) {
        client.GET(config.testCollection, function(err, usergridResponse) {
            usergridResponse.hasNextPage.should.be.true()
            done()
        })
    })

    it('should be false when no more entities exist', function(done) {
        client.GET('users', function(err, usergridResponse) {
            usergridResponse.metadata.count.should.be.lessThan(10)
            usergridResponse.hasNextPage.should.not.be.true()
            done()
        })
    })
})