'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('underscore')

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) {
            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()
        })
    })
})