require( '../setup.js' );
var nock = require( 'nock' );
//nock.disableNetConnect();

var adapterConfig = require( '../../src/index' );

describe( 'Adapter', function() {
	var oldExit = process.exit;
	var calledExit = null;
	var boundary;
	var timestamp = Date.now();
	var metric = {
		type: 'time',
		units: 'ms',
		value: 100,
		key: 'DF.myserver.some.key',
		timestamp: timestamp
	};
	before( function() {
		boundary = nock( 'https://premium-api.boundary.com', {
			reqheaders: { authorization: 'Basic dGVzdDp0ZXN0' }
		} );
		process.exit = function( code ) {
			calledExit = code;
		};
	} );

	describe( 'with missing credentials', function() {
		before( function( done ) {
			adapterConfig( {}, done );
		} );

		it( 'should exit', function() {
			calledExit.should.equal( -1 );
		} );

		after( function() {
			calledExit = null;
		} );
	} );

	describe( 'with failing metric retrieval', function() {
		before( function( done ) {
			boundary
				.get( '/v1/metrics' )
				.reply( 401, 'I hate you' );
			adapterConfig( { email: 'test', token: 'test' }, done );
		} );

		it( 'should call boundary', function() {
			boundary.done();
		} );

		it( 'should exit', function() {
			calledExit.should.equal( -1 );
		} );

		after( function() {
			nock.cleanAll();
			calledExit = null;
		} );
	} );

	describe( 'with failing metric creation', function() {
		var adapter;
		before( function( done ) {
			boundary
				.get( '/v1/metrics' )
				.reply( 200, [ {} ] )
				.put( '/v1/metrics/LK_SOME_KEY',
					{
						description: 'some key',
						displayName: 'some key',
						displayNameShort: 'some key',
						unit: 'duration',
						defaultAggregate: 'avg',
						defaultResolutionMS: 1000,
						isDisabled: false
					} )
				.reply( 401, 'Never. Never. EVER!' );

			adapter = adapterConfig( { namespace: 'LK', hasPrefix: true, email: 'test', token: 'test' }, function() {
				adapter.setConverter( function( x ) {
					return x;
				} );
				adapter.onMetric( metric );
				setTimeout( function() {
					done();
				}, 100 );
			} );
		} );

		it( 'should make all calls to boundary', function() {
			boundary.done();
		} );

		after( function() {
			nock.cleanAll();
		} );
	} );

	describe( 'with consecutive failing measurements', function() {
		var adapter;
		before( function( done ) {
			boundary
				.get( '/v1/metrics' )
				.reply( 200, [ {} ] )
				.put( '/v1/metrics/SOME_KEY',
					{
						description: 'some key',
						displayName: 'some key',
						displayNameShort: 'some key',
						unit: 'duration',
						defaultAggregate: 'avg',
						defaultResolutionMS: 1000,
						isDisabled: false
					} )
				.reply( 200, 'Cool beans' )
				.post( '/v1/measurements', {
					source: 'DF-myserver',
					metric: 'SOME_KEY',
					measure: 100,
					timestamp: timestamp
				} )
				.reply( 400, 'No thanks' )
				.post( '/v1/measurements', {
					source: 'DF-myserver',
					metric: 'SOME_KEY',
					measure: 100,
					timestamp: timestamp
				} )
				.reply( 400, 'This gets a NOPE' )
				.post( '/v1/measurements', {
					source: 'DF-myserver',
					metric: 'SOME_KEY',
					measure: 100,
					timestamp: timestamp
				} )
				.reply( 400, 'This gets a NOPE' );

			adapter = adapterConfig( { hasPrefix: true, email: 'test', token: 'test' }, function() {
				adapter.setConverter( function( x ) {
					return x;
				} );
				adapter.onMetric( metric );
				adapter.onMetric( metric );
				adapter.onMetric( metric );
				setTimeout( function() {
					done();
				}, 200 );
			} );
		} );

		it( 'should make all calls to boundary', function() {
			boundary.done();
		} );

		it( 'should exit', function() {
			calledExit.should.equal( -1 );
		} );

		after( function() {
			nock.cleanAll();
			calledExit = null;
		} );
	} );

	describe( 'with existing metric creation', function() {
		var adapter;
		before( function( done ) {
			boundary
				.get( '/v1/metrics' )
				.reply( 200, [ { name: 'LK_SOME_KEY' } ] )
				.post( '/v1/measurements',
					{
						source: 'DF-myserver',
						metric: 'LK_SOME_KEY',
						measure: 100,
						timestamp: timestamp
					} )
				.reply( 200, 'Huzzah' );

			adapter = adapterConfig( { namespace: 'LK', hasPrefix: true, email: 'test', token: 'test' }, function() {
				adapter.setConverter( function( x ) {
					return x;
				} );
				adapter.onMetric( metric );
				setTimeout( function() {
					done();
				}, 100 );
			} );
		} );

		it( 'should make all calls to boundary', function() {
			boundary.done();
		} );

		after( function() {
			calledExit = null;
		} );
	} );

	after( function() {
		nock.cleanAll();
		process.exit = oldExit;
	} );
} );
