/**
* Copyright Super iPaaS Integration LLC, an IBM Company 2024
*/
/* eslint-disable @typescript-eslint/no-var-requires */
import { INVALID_PROJECT_NAMES } from '../../constants/message-constants';
import {checkForRootDirPermission, checkIfAllProjectExists, checkIfRootDirExists, getAllProjectNames, getOtherProjectsNames} from './root-dir-helper';

jest.mock('../common/message-helper', () => ({
	__esModule: true,
	showError: jest.fn()
}));


describe('root dir helper test suite', () => {

	it('should true, if the root dir permission is available', () => {
		const readAccessSpy = jest.spyOn( require('../common/fs-helper'), 'hasReadAccess');
		readAccessSpy.mockImplementation(() => true);
        
		expect(checkForRootDirPermission('')).toBeTruthy();
	});

	it('should throw error, if the root dir permission is not available', () => {
		const readAccessSpy = jest.spyOn( require('../common/fs-helper'), 'hasReadAccess');
		readAccessSpy.mockImplementation(() => false);

		expect(() => checkForRootDirPermission('abc')).toThrow('No read access for the path: abc');
	});

	it('should throw error, if the root dir do not exist', () => {
		const isDirectorySpy = jest.spyOn( require('../common/fs-helper'), 'isDirectory');
		isDirectorySpy.mockImplementation(() => false);
		expect(() => checkIfRootDirExists('abc')).toThrow('The local directory path \'abc\' is either not a directory or does not exist.');
	});

	it('should throw error, if the root dir exist', () => {
		const isDirectorySpy = jest.spyOn(require('../common/fs-helper'), 'isDirectory');
		isDirectorySpy.mockImplementation(() => true);

		expect(checkIfRootDirExists('abc')).toBeTruthy();
	});

	it('should return array of project, for a given root path', () => {
		const isDirectorySpy = jest.spyOn(require('../common/fs-helper'), 'isDirectory');
		isDirectorySpy.mockImplementation(() => true);
		const readAccessSpy = jest.spyOn( require('../common/fs-helper'), 'hasReadAccess');
		readAccessSpy.mockImplementation(() => true);
		const readFileSpy = jest.spyOn(require('../common/fs-helper'), 'readFile');
		readFileSpy.mockImplementation(() => {});
		const readYamlSpy = jest.spyOn(require('../common/yaml-helper'), 'readYaml');
		readYamlSpy.mockImplementation(() => {
			return {
				projects: {
					projA: {

					},
					projB: {

					}
				}
			};
		});
		expect(getAllProjectNames('xyz')).toBe('projA,projB');
	});

	it('should return set of other project names excluding current projects', () => {
		const isDirectorySpy = jest.spyOn(require('../common/fs-helper'), 'isDirectory');
		isDirectorySpy.mockImplementation(() => true);

		const readAccessSpy = jest.spyOn(require('../common/fs-helper'), 'hasReadAccess');
		readAccessSpy.mockImplementation(() => true);

		const readFileSpy = jest.spyOn(require('../common/fs-helper'), 'readFile');
		readFileSpy.mockImplementation(() => 'mockYamlContent');

		const readYamlSpy = jest.spyOn(require('../common/yaml-helper'), 'readYaml');
		readYamlSpy.mockImplementation(() => ({
			projects: {
				projA: {},
				projB: {},
				projC: {}
			}
		}));

		const result = getOtherProjectsNames('xyz', 'projA,projC');
		expect(result).toEqual(new Set(['projB']));
	});

	it('should throw error if project names are null or undefined in checkIfAllProjectExists', () => {
		expect(() => checkIfAllProjectExists('xyz', null as unknown as string))
			.toThrow(INVALID_PROJECT_NAMES);
	});

	it('should throw error if project directory does not exist', () => {
		const isSubDirectoryExistsSpy = jest.spyOn(require('../common/fs-helper'), 'isSubDirectoryExists');
		isSubDirectoryExistsSpy.mockImplementation(() => false);

		expect(() => checkIfAllProjectExists('xyz', 'projA'))
			.toThrow('The project \'projA\' does not exist in the local directory \'xyz\'');
	});

	it('should return true if all project directories exist', () => {
		const isSubDirectoryExistsSpy = jest.spyOn(require('../common/fs-helper'), 'isSubDirectoryExists');
		isSubDirectoryExistsSpy.mockImplementation(() => true);

		expect(checkIfAllProjectExists('xyz', 'projA,projB')).toBeTruthy();
	});
});