var rfr = require('rfr');
var Lab = require('lab');
var lab = exports.lab = Lab.script();
var expect = require('code').expect;

var Storage = rfr('app/models/Storage.js');
var Router = rfr('app/Router.js');

var TestUtils = rfr('test/TestUtils');
var Service = rfr('app/services/Service');
var Authenticator = rfr('app/policies/Authenticator');

var testAccount = {
  userId: 1, username: 'bob', password: 'abc', scope: Authenticator.SCOPE.ADMIN
};

var admin = {
  username: 'Bob',
  password: 'generated'
};

lab.experiment('AdminController Function Tests', function() {
  lab.beforeEach({timeout: 10000}, function(done) {
    TestUtils.resetDatabase(done);
  });

  lab.test('Create admin', function(done) {
    Service.createNewAdmin(admin).then(function(result) {
      return Service.getAdminByUsername(result.username);
    }).then(function(user) {
      expect(user.username).to.equal(admin.username);
      done();
    });
  });
});

lab.experiment('AdminController Routes tests', function() {
  lab.beforeEach(function(done) {
    TestUtils.resetDatabase(done);
  });

  lab.test('Unauthorized to public routes', function(done) {
    var routes = {
      POST: [
        '/api/admins'
      ]
    };

    var checkUnauthorized = function(method, url) {
      Router.inject({method: method, url: url}, function(res) {
        expect(res.statusCode).to.equal(401);
      });
    };

    routes.POST.map((url) => checkUnauthorized('POST', url));
    done();
  });

  lab.test('Create admin without params or credentials', function(done) {
    Router.inject({
      method: 'POST', url: '/api/admins'
    }, function(res) {
      expect(res.statusCode).to.equal(401);
    });

    Router.inject({
      method: 'POST', url: '/api/admins', credentials: testAccount
    }, function(res) {
      expect(res.statusCode).to.equal(400);
    });

    done();
  });

  lab.test('Login without params', function(done) {
    Router.inject({
      method: 'POST', url: '/api/admins/login'
    }, function(res) {
      expect(res.statusCode).to.equal(400);
      done();
    });
  });

  lab.test('Login with invalid credentials', function(done) {
    Router.inject({
      method: 'POST', url: '/api/admins/login', payload: admin
    }, function(res) {
      expect(res.statusCode).to.equal(401);
      done();
    });
  });

  lab.test('Create admin, login, and access authorized route', function(done) {
    Router.inject({
      method: 'POST', url: '/api/admins', credentials: testAccount,
      payload: admin
    }, function checkCreation(res) {
      expect(res.statusCode).to.equal(201);
      expect(TestUtils.isEqualOnProperties(
          admin, JSON.parse(res.payload)
      )).to.be.true();

      Router.inject({
        method: 'POST', url: '/api/admins/login', payload: admin
      }, function checkLoggedIn(res) {
        expect(res.statusCode).to.equal(200);
        expect(TestUtils.isEqualOnProperties(
            admin, JSON.parse(res.payload)
        )).to.be.true();

        Router.inject({
          method: 'POST', url: '/api/admins',
          headers: {'Cookie': res.headers['set-cookie'][0].split(';')[0]}
        }, function checkValidCredentials(res) {
          // 401 if invalid credentials
          expect(res.statusCode).to.equal(400);
          done();
        });
      });
    });
  });

  lab.test('Logout', function(done) {
    Router.inject({
      method: 'GET', url: '/api/admins/logout'
    }, function(res) {
      expect(res.statusCode).to.equal(200);
      expect(res.result).to.equal('Logged out');
      done();
    });
  });
});

@@ -335,24 +335,239 @@
 ticator');%0A%0A
+var rootAdminPermissions = %5B%0A  Authenticator.SCOPE.ADMIN.METRICS,%0A  Authenticator.SCOPE.ADMIN.STREAMS,%0A  Authenticator.SCOPE.ADMIN.USERS,%0A  Authenticator.SCOPE.ADMIN.ADMINS,%0A  Authenticator.SCOPE.ADMIN.SETTINGS%0A%5D;%0A%0A
 var testAcco
@@ -632,33 +632,28 @@
 pe: 
-Authenticator.SCOPE.ADMIN
+rootAdminPermissions
 %0A%7D;%0A
@@ -714,16 +714,105 @@
 ed'%0A%7D;%0A%0A
+var rootAdmin = Object.assign(%7B%7D, admin);%0ArootAdmin.permissions = rootAdminPermissions;%0A%0A
 lab.expe
@@ -2788,33 +2788,37 @@
 %0A      payload: 
-a
+rootA
 dmin%0A    %7D, func
@@ -3069,33 +3069,37 @@
 ogin', payload: 
-a
+rootA
 dmin%0A      %7D, fu
@@ -3303,32 +3303,32 @@
 Router.inject(%7B%0A
-
           method
@@ -3356,16 +3356,29 @@
 admins',
+ payload: %7B%7D,
 %0A       

Update test for new admin scopes