import { setEvents } from '../logic/sources/setEvents';

import { ValidAccessKey } from '@event-inc/types';
import { createSource } from '../logic/sources/createSource';
import {
	createDestination,
	deleteDestination,
	deleteSource,
	listDestinations,
	listSources,
	getParser
} from '../logic';
import { makeId } from '@event-inc/utils';
import { createClient } from '../client';

require('dotenv').config();
jest.setTimeout(30000);

describe('Connections APIs Specs', () => {
	it('Should create a Stripe source, subscribe to customer.created event, create a mongodb destination', async () => {
		const client = createClient(
			process.env.BUILDABLE_SECRET_KEY,
			{
				baseUrl: process.env.EVENT_INC_API_BASE_URL
			}
		);

		const source = await createSource(client, {
			type: 'stripe',
			group: `my-stripe-source-${makeId(4)}`,
			label: `My Stripe Source ${makeId(4)}`,
			config: {
				STRIPE_SECRET_KEY: process.env.CONNECTIONS_TEST_STRIPE_SECRET_KEY,
			},
		});

		expect(source).toHaveProperty('key');

		await new Promise((resolve) => setTimeout(resolve, 5000));

		const subscribe = await setEvents(client, {
			type: 'stripe',
			key: source.key,
			events: ['customer.created'],
		});

		expect(subscribe).toHaveProperty('success', true);

		const destination = await createDestination(client, {
			type: 'mongodb',
			group: `my-mongodb-destination-${makeId(4)}`,
			label: `My MongoDB Destination ${makeId(4)}`,
			config: {
				MONGODB_URI: process.env.CONNECTIONS_TEST_MONGODB_URI,
			},
		});

		expect(destination).toHaveProperty('key');

		await new Promise((resolve) => setTimeout(resolve, 5000));

		const deleteSourceResult = await deleteSource(client, {
			key: source.key,
		});

		expect(deleteSourceResult).toHaveProperty('success', true);

		const deleteDestinationResult = await deleteDestination(client, {
			key: destination.key,
		});

		expect(deleteDestinationResult).toHaveProperty('success', true);
	});

	it('Should create an FTP source with a custom parser', async () => {
		const client = createClient(
			process.env.BUILDABLE_SECRET_KEY as ValidAccessKey,
			{
				baseUrl: process.env.EVENT_INC_API_BASE_URL
			}
		);

		const source = await createSource<"ftp">(client, {
			type: 'ftp',
			group: `my-ftp-${makeId(4)}`,
			label: `FTP Source with a custom parser - ${makeId(4)}`,
			config: {
				FTP_HOST: process.env.CONNECTIONS_TEST_FTP_HOST,
				FTP_USER: process.env.CONNECTIONS_TEST_FTP_USER,
				FTP_PASSWORD: process.env.CONNECTIONS_TEST_FTP_PASSWORD,
				FTP_PATH: process.env.CONNECTIONS_TEST_FTP_PATH,	
				FTP_PORT: process.env.CONNECTIONS_TEST_FTP_PORT,
				FTP_SCAN_INTERVAL: '*/1 * * * *',
				FTP_FILE_ARCHIVING_ENABLED: "Y",
				FTP_FILE_EXTRACTION_ENABLED: "Y",
				FTP_EXTRACTOR_FILE_TYPE: "csv",
				FTP_PARSER: function parseCSV (payload: string): {
					[key: string]: string
				}[] {
					const [headerLine, ...dataLines] = payload.split("\n");
				
					const delimiter = ",";
					const headers = headerLine.split(delimiter);
				
					return dataLines.map((line) => {
						const cells = line.split(delimiter);
				
						return headers.reduce((obj: {
							[key: string]: string
						}, header, index) => {
							obj[header] = cells[index] + " | custom"
				
							return obj;
						}, {});
					});
				},
				FTP_EXTRACTOR_FILE_SIZE_LIMIT: "2mb",
				FTP_EXTRACTOR_RECORD_COUNT_LIMIT: "25"
			}
		});

		console.log(source);

		expect(source.parser).toBeDefined();
	});

	it('Should create an FTP source with a default CSV parser', async () => {
		const client = createClient(
			process.env.BUILDABLE_SECRET_KEY as ValidAccessKey,
			{
				baseUrl: process.env.EVENT_INC_API_BASE_URL
			}
		);

		const source = await createSource<"ftp">(client, {
			type: 'ftp',
			group: `my-ftp-${makeId(4)}`,
			label: `FTP Source with a default csv parser - ${makeId(4)}`,
			config: {
				FTP_HOST: process.env.CONNECTIONS_TEST_FTP_HOST,
				FTP_USER: process.env.CONNECTIONS_TEST_FTP_USER,
				FTP_PASSWORD: process.env.CONNECTIONS_TEST_FTP_PASSWORD,
				FTP_PATH: process.env.CONNECTIONS_TEST_FTP_PATH,	
				FTP_PORT: process.env.CONNECTIONS_TEST_FTP_PORT,
				FTP_SCAN_INTERVAL: '*/1 * * * *',
				FTP_FILE_ARCHIVING_ENABLED: "Y",
				FTP_FILE_EXTRACTION_ENABLED: "Y",
				FTP_EXTRACTOR_FILE_TYPE: "csv",
				FTP_PARSER: "csv",
				FTP_EXTRACTOR_FILE_SIZE_LIMIT: "2mb",
				FTP_EXTRACTOR_RECORD_COUNT_LIMIT: "25"
			}
		});

		console.log(source);

		expect(source.parser).toBeDefined();
	});

	it('Should create an FTP source with a default JSON parser', async () => {
		const client = createClient(
			process.env.BUILDABLE_SECRET_KEY as ValidAccessKey,
			{
				baseUrl: process.env.EVENT_INC_API_BASE_URL
			}
		);

		const source = await createSource<"ftp">(client, {
			type: 'ftp',
			group: `my-ftp-${makeId(4)}`,
			label: `FTP Source with a default JSON parser - ${makeId(4)}`,
			config: {
				FTP_HOST: process.env.CONNECTIONS_TEST_FTP_HOST,
				FTP_USER: process.env.CONNECTIONS_TEST_FTP_USER,
				FTP_PASSWORD: process.env.CONNECTIONS_TEST_FTP_PASSWORD,
				FTP_PATH: process.env.CONNECTIONS_TEST_FTP_PATH,	
				FTP_PORT: process.env.CONNECTIONS_TEST_FTP_PORT,
				FTP_SCAN_INTERVAL: '*/1 * * * *',
				FTP_FILE_ARCHIVING_ENABLED: "Y",
				FTP_FILE_EXTRACTION_ENABLED: "Y",
				FTP_EXTRACTOR_FILE_TYPE: "json",
				FTP_PARSER: "json",
				FTP_EXTRACTOR_FILE_SIZE_LIMIT: "2mb",
				FTP_EXTRACTOR_RECORD_COUNT_LIMIT: "25"
			}
		});

		console.log(source);

		expect(source.parser).toBeDefined();
	});

	it('Should get an FTP source parser function', async () => {
		const client = createClient(
			process.env.BUILDABLE_SECRET_KEY as ValidAccessKey,
			{
				baseUrl: process.env.EVENT_INC_API_BASE_URL
			}
		);

		const source = await createSource<"ftp">(client, {
			type: 'ftp',
			group: `my-ftp-${makeId(4)}`,
			label: `FTP Source - ${makeId(4)}`,
			config: {
				FTP_HOST: process.env.CONNECTIONS_TEST_FTP_HOST,
				FTP_USER: process.env.CONNECTIONS_TEST_FTP_USER,
				FTP_PASSWORD: process.env.CONNECTIONS_TEST_FTP_PASSWORD,
				FTP_PATH: process.env.CONNECTIONS_TEST_FTP_PATH,	
				FTP_PORT: process.env.CONNECTIONS_TEST_FTP_PORT,
				FTP_SCAN_INTERVAL: '*/1 * * * *',
				FTP_FILE_ARCHIVING_ENABLED: "Y",
				FTP_FILE_EXTRACTION_ENABLED: "Y",
				FTP_EXTRACTOR_FILE_TYPE: "json",
				FTP_PARSER: "json",
				FTP_EXTRACTOR_FILE_SIZE_LIMIT: "2mb",
				FTP_EXTRACTOR_RECORD_COUNT_LIMIT: "25"
			}
		});

		const parser = await getParser(client, {
			key: source.key
		});

		console.log(parser)

		expect(parser).toBeDefined();
	});

	it('Should list all sources', async () => {
		const client = createClient(
			process.env.BUILDABLE_SECRET_KEY as ValidAccessKey,
			{
				baseUrl: process.env.EVENT_INC_API_BASE_URL
			}
		);

		const sourceList = await listSources(client);

		expect(sourceList).toHaveProperty('rows');
	});

	it('Should list all destinations', async () => {
		const client = createClient(
			process.env.BUILDABLE_SECRET_KEY as ValidAccessKey,
			{
				baseUrl: process.env.EVENT_INC_API_BASE_URL
			}
		);

		const destinationList = await listDestinations(client);

		expect(destinationList).toHaveProperty('rows');
	});

	it('Should create a kafka destination', async () => {
		const client = createClient(
			process.env.BUILDABLE_SECRET_KEY as ValidAccessKey,
			{
				baseUrl: process.env.EVENT_INC_API_BASE_URL
			}
		);

		const destination = await createDestination(client, {
			type: 'kafka',
			group: `my-kafka-${makeId(4)}`,
			label: `Kafka Destination - ${makeId(4)}`,
			config: {
				KAFKA_CLIENT_ID: 'my-kafka-client-id',
				KAFKA_BROKER_URLS: process.env.KAFKA_BROKER_URLS,
				KAFKA_USERNAME: process.env.KAFKA_USERNAME,
				KAFKA_PASSWORD: process.env.KAFKA_PASSWORD,
			}
		});

		console.log('destination',destination)

		expect(destination).toBeDefined();
	});

	it('Should create a Rutter source', async () => {
		const client = createClient(
			process.env.BUILDABLE_SECRET_KEY as ValidAccessKey,
			{
				baseUrl: process.env.EVENT_INC_API_BASE_URL
			}
		);

		const source = await createSource<"rutter">(client, {
			type: 'rutter',
			group: `my-rutter-${makeId(4)}`,
			label: `Rutter - ${makeId(4)}`
		});

		console.log(source);

		expect(source.frontend.spec.type).toBe("rutter");
	});

	it('Should create an Microsort SQL Server Destination', async () => {
		const client = createClient(
			process.env.BUILDABLE_SECRET_KEY as ValidAccessKey,
			{
				baseUrl: process.env.EVENT_INC_API_BASE_URL
			}
		);

		const source = await createDestination<"mssql">(client, {
			type: 'mssql',
			group: `my-mssql-${makeId(4)}`,
			label: `Microsoft SQL Server - ${makeId(4)}`,
			config: {
				MSSQL_DATABASE: process.env.MSSQL_DATABASE,
				MSSQL_HOST: process.env.MSSQL_HOST,
				MSSQL_PASSWORD: process.env.MSSQL_PASSWORD,
				MSSQL_PORT: process.env.MSSQL_PORT,
				MSSQL_USERNAME: process.env.MSSQL_USERNAME,
			}
		});

		console.log(source);

		expect(source.frontend.spec.type).toBe("mssql");
	});
});

