'use strict';

var assert = require('assert');

var Node = require('../../lib/node/node');
var DatabaseService = require('../../lib/service/database');
var Factory = require('../../lib/workflow/factory');
var Sampling = require('../../lib/node/nodes/sampling');

var TestConfig = require('../test-config');

const RANGE_FILTERS_ERROR_MESSAGE = 'Range filter expect to have at least one value in ' +
                                    'greater_than, greater_than_or_equal, ' +
                                    'less_than, less_than_or_equal, min, or max numeric params';

describe('factory', function() {

    before(function() {
        var configuration = TestConfig.create({ batch: { inlineExecution: true } });
        this.configuration = configuration;
        this.databaseService = new DatabaseService(
            configuration.user,
            configuration.db,
            configuration.batch,
            configuration.limits
        );
    });

    it('basic test-source node', function(done) {
        var TEST_SOURCE_TYPE = 'test-source';
        var TestSource = Node.create(TEST_SOURCE_TYPE, {
            table: Node.PARAM.STRING()
        }, { cache: true });
        TestSource.prototype.sql = function() {
            return 'select * from ' + this.table;
        };

        var definition = {
            type: TEST_SOURCE_TYPE,
            params: {
                table: 'airbnb_rooms'
            }
        };

        var typeNodeMap = {};
        typeNodeMap[TEST_SOURCE_TYPE] = TestSource;

        var factory = new Factory(this.configuration.user, this.databaseService, typeNodeMap);
        factory.create(definition, function(err, rootNode) {
            assert.ifError(err);

            assert.equal(rootNode.getType(), TEST_SOURCE_TYPE);
            assert.equal(rootNode.sql(), 'select * from airbnb_rooms');
            assert.ok(rootNode.getQuery().match(/^select \* from analysis_/));

            return done();
        });
    });

    it('invalid filters in createCacheTable', function(done) {
        const TEST_SOURCE_TYPE = 'test-source';
        const TestSource = Node.create(TEST_SOURCE_TYPE, {
            table: Node.PARAM.STRING()
        }, { cache: true });
        TestSource.prototype.sql = function() {
            return 'select * from ' + this.table;
        };

        const invalid_filters = {
            price: {
                type: 'range',
                column: 'price',
                params: {
                }
            }
        };
        const sourceDefinition = {
            type: TEST_SOURCE_TYPE,
            params: {
                table: 'airbnb_rooms',
            }
        };
        const samplingDefinition = {
            type: 'sampling',
            params: {
                source: sourceDefinition,
                sampling: 1,
                seed: 12345,
                filters: invalid_filters
            }
        };
        const definition = {
            type: 'sampling',
            params: {
                source: samplingDefinition,
                sampling: 1,
                seed: 12345,
            }
        };

        const typeNodeMap = {};
        typeNodeMap[TEST_SOURCE_TYPE] = TestSource;
        typeNodeMap.sampling = Sampling;

        const factory = new Factory(this.configuration.user, this.databaseService, typeNodeMap);
        factory.create(definition, function(err) {
            assert.equal(err.message, RANGE_FILTERS_ERROR_MESSAGE);
            return done();
        });
    });
});

@@ -3255,16 +3255,1088 @@
 pling;%0A%0A
+        const factory = new Factory(this.configuration.user, this.databaseService, typeNodeMap);%0A        factory.create(definition, function(err) %7B%0A            assert.equal(err.message, RANGE_FILTERS_ERROR_MESSAGE);%0A            return done();%0A        %7D);%0A    %7D);%0A%0A    it('invalid filters in getColumns', function(done) %7B%0A        const TEST_SOURCE_TYPE = 'test-source';%0A        const TestSource = Node.create(TEST_SOURCE_TYPE, %7B%0A            table: Node.PARAM.STRING()%0A        %7D, %7B cache: true %7D);%0A        TestSource.prototype.sql = function() %7B%0A            return 'select * from ' + this.table;%0A        %7D;%0A%0A        const invalid_filters = %7B%0A            price: %7B%0A                type: 'range',%0A                column: 'price',%0A                params: %7B%0A                %7D%0A            %7D%0A        %7D;%0A        const definition = %7B%0A            type: TEST_SOURCE_TYPE,%0A            params: %7B%0A                table: 'airbnb_rooms',%0A                filters: invalid_filters%0A            %7D%0A        %7D;%0A%0A        const typeNodeMap = %7B%7D;%0A        typeNodeMap%5BTEST_SOURCE_TYPE%5D = TestSource;%0A%0A
         

Add test for catching range errors in getColumns