// @flow
import React from 'react';
import { expect } from 'chai';
import { mount } from 'enzyme';
import sinon from 'sinon';
import { spies } from '../../test';

import C from './ValidSchemaBadge.jsx';

import testAlgs from '@test/test_algs.json';
import testLibs from '@test/test_libs.json';
import testDfs from '@test/test_dfs.json';
import testDbs from '@test/test_dbs.json';
import {  getValidAlgorithmObj as getValidObj } from '@helpers/beat';

describe('<ValidSchemaBadge />', () => {
	let wrapper;
	afterEach(() => {
		if(wrapper && wrapper.unmount)
			wrapper.unmount();
	});

	const invalidTestAlgNames = [`test/pcatest/1`, `test/testing/1`];

	describe('should accept', () => {
		describe('database', () => {
			const dbs = [
				{
					name: 'test/test/1',
					contents: {
						'root_folder': '/testing',
						description: 'this is the basic test case for database schema validation',
						protocols: [
							{
								name: 'protocol_1',
								template: 'template_1',
								sets: [
									{
										name: 'set_1',
										view: 'view_1',
										template: 'set_template_1',
										parameters: {
											param1: 'i dont know what these are'
										},
										outputs: {
											output_1: 'a/specific_dataformat/1',
										}
									}
								]
							}
						]
					}
				}
			].concat(testDbs);

			dbs.forEach(function(db) {
				it(`${ db.name }`, () => {
					wrapper = mount(<C entity='database' obj={db} />);
					expect(wrapper.find('Badge')).to.have.prop('color', 'success');
				});
			});
		});

		describe('algorithm', () => {
			const algs = [
				{
					name: 'test/non-analyzer-alg/1',
					contents: {
						language: 'python',
						description: 'A basic algorithm as a sanity test for the AlgorithmEditor',
						groups: [
							{
								name: 'group_1',
								inputs: {
									'input_1': { type: 'test/df/1' },
								},
								outputs: {
									'output_1': { type: 'test/df/2' },
								},
							}
						],
						uses: {
							'library_1': 'a/lib/1',
						},
						parameters: {
							'parameter_1': {
								type: 'string',
								choice: [
									'choice_1',
									'choice_2',
									'choice_3',
								],
								default: 'choice_1',
							}
						},
						// non-analyzer
						splittable: false,
						schema_version: 3.0,
						api_version: 2.0,
						type: 'sequential',
					}
				}
			].concat(
				testAlgs
				.filter(a => !invalidTestAlgNames.includes(a.name))
				.map(a => getValidObj(a))
			);

			algs.forEach(function(alg) {
				it(`${ alg.name }`, () => {
					wrapper = mount(<C entity='algorithm' obj={alg} />);
					expect(wrapper.find('Badge')).to.have.prop('color', 'success');
				});
			});
		});

		describe('dataformat', () => {
			const dfs = [
				{
					name: 'test/df/1',
					contents: {
						'field_1': 'string',
					}
				}
			].concat(testDfs);

			dfs.forEach(function(df) {
				it(`${ df.name }`, () => {
					wrapper = mount(<C entity='dataformat' obj={df} />);
					expect(wrapper.find('Badge')).to.have.prop('color', 'success');
				});
			});
		});
		describe('library', () => {
			const libs = [
				{
					name: 'test/lib/1',
					contents: {
						language: 'python',
					}
				}
			].concat(testLibs);

			libs.forEach(function(lib) {
				it(`${ lib.name }`, () => {
					wrapper = mount(<C entity='library' obj={lib} />);
					expect(wrapper.find('Badge')).to.have.prop('color', 'success');
				});
			});
		});
	});

	describe('should reject', () => {
		describe('database', () => {
			const dbs = [
				{
					name: 'test/test/1',
					contents: {
						'root_folder': '/testing',
						description: 'this is the basic test case for database schema validation',
						protocols: [
							{
								name: 'protocol_1',
								template: 'template_1',
								sets: [
									{
										name: 'set_1',
										view: 'view_1',
										template: 'set_template_1',
										parameters: {
											param1: 'i dont know what these are'
										},
										outputs: {
											output_1: 'a/wrong/output',
										}
									}
								]
							}
						]
					}
				},
				{
					name: 'test/test/1',
					contents: {
						description: 'this is the basic test case for database schema validation',
						protocols: [
							{
								name: 'protocol_1',
								template: 'template_1',
								sets: [
									{
										name: 'set_1',
										view: 'view_1',
										template: 'set_template_1',
										parameters: {
											param1: 'i dont know what these are'
										},
										outputs: {
											output_1: 'a/wrong/output',
										}
									}
								]
							}
						]
					}
				}
			];

			dbs.forEach(function(db) {
				it(`${ db.name }`, () => {
					wrapper = mount(<C entity='database' obj={db} />);
					expect(wrapper.find('Badge')).to.have.prop('color', 'danger');
				});
			});
		});

		describe('algorithm', () => {
			const algs = testAlgs
			.filter(a => invalidTestAlgNames.includes(a.name))
			.map(a => getValidObj(a));

			algs.forEach(function(alg) {
				it(`${ alg.name }`, () => {
					wrapper = mount(<C entity='algorithm' obj={alg} />);
					expect(wrapper.find('Badge')).to.have.prop('color', 'danger');
				});
			});
		});
	});
});
