import { createBuildZip } from '../../helpers/common/fs-helper.js';
import { getOutputPath } from './../helpers/build-action-helper.js';
import { showInfo, showWarning } from '../../helpers/common/message-helper.js';
import { CREATED_DEPLOY_ZIP, IGNORE_PROJECT_ARG, IGNORE_NAMES_OPT } from '../../constants/message-constants.js';
import { buildAssets, buildProjects } from '../helpers/build-action-helper.js';
import { writeArchive, buildAssetsOrProjects } from './deploy-action-helper.js';

jest.mock('../../helpers/common/fs-helper', () => ({
    createBuildZip: jest.fn(),
}));

jest.mock('../helpers/build-action-helper.js', () => ({
    getOutputPath: jest.fn(),
    buildAssets: jest.fn(),
    buildProjects: jest.fn(),
}));

jest.mock('../../helpers/common/message-helper.js', () => ({
    showInfo: jest.fn(),
    showWarning: jest.fn(),
}));

describe('Deploy action helper Test Suite', () => {

    describe('writeArchive', () => {
        afterEach(() => {
            jest.clearAllMocks();
        });

        it('should call createBuildZip and showInfo with correct message when zip is created successfully', async () => {
            const projects = 'project';
            const all = false;
            const names = 'name';
            const zipBuffer = Buffer.from('test');
            const zipFileName = 'path/to/zipfile.zip';
            
            (getOutputPath as jest.Mock).mockResolvedValue(zipFileName);
            (createBuildZip as jest.Mock).mockReturnValue(true);

            await writeArchive(projects, all, names, zipBuffer);

            expect(createBuildZip).toHaveBeenCalledWith(zipBuffer, zipFileName);
            expect(showWarning).toHaveBeenCalledWith(CREATED_DEPLOY_ZIP + zipFileName);
        });

        it('should not call showInfo when createBuildZip fails', async () => {
            const projects = 'project';
            const all = false;
            const names = 'name';
            const zipBuffer = Buffer.from('test');
            const zipFileName = 'path/to/zipfile.zip';

            (getOutputPath as jest.Mock).mockResolvedValue(zipFileName);
            (createBuildZip as jest.Mock).mockReturnValue(false);

            await writeArchive(projects, all, names, zipBuffer);

            expect(createBuildZip).toHaveBeenCalledWith(zipBuffer, zipFileName);
            expect(showInfo).not.toHaveBeenCalled();
        });
    });

    describe('buildAssetsOrProjects', () => {
        afterEach(() => {
            jest.clearAllMocks();
        });

        it('should call buildAssets if names is provided and all is false', async () => {
            const projects = 'project';
            const all = false;
            const names = 'name';
            const localDir = 'local/dir';
            const zipBuffer = Buffer.from('test');

            (buildAssets as jest.Mock).mockResolvedValue(zipBuffer);

            const result = await buildAssetsOrProjects(projects, all, names, localDir);

            expect(buildAssets).toHaveBeenCalledWith(names, localDir, projects);
            expect(buildProjects).not.toHaveBeenCalled();
            expect(result).toBe(zipBuffer);
        });

        it('should call showWarning with IGNORE_PROJECT_ARG if projects and all are provided', async () => {
            const projects = 'project';
            const all = true;
            const names = 'name';
            const localDir = 'local/dir';
            const zipBuffer = Buffer.from('test');

            (buildProjects as jest.Mock).mockResolvedValue(zipBuffer);

            await buildAssetsOrProjects(projects, all, names, localDir);

            expect(showWarning).toHaveBeenCalledWith(IGNORE_PROJECT_ARG);
            expect(buildProjects).toHaveBeenCalledWith(all, localDir, projects);
        });

        it('should call showWarning with IGNORE_NAMES_OPT if names and all are provided', async () => {
            const projects = 'project';
            const all = true;
            const names = 'name';
            const localDir = 'local/dir';
            const zipBuffer = Buffer.from('test');

            (buildProjects as jest.Mock).mockResolvedValue(zipBuffer);

            await buildAssetsOrProjects(projects, all, names, localDir);

            expect(showWarning).toHaveBeenCalledWith(IGNORE_NAMES_OPT);
            expect(buildProjects).toHaveBeenCalledWith(all, localDir, projects);
        });

        it('should call buildProjects if names is not provided or all is false', async () => {
            const projects = 'project';
            const all = false;
            const names = '';
            const localDir = 'local/dir';
            const zipBuffer = Buffer.from('test');

            (buildProjects as jest.Mock).mockResolvedValue(zipBuffer);

            const result = await buildAssetsOrProjects(projects, all, names, localDir);

            expect(buildProjects).toHaveBeenCalledWith(all, localDir, projects);
            expect(buildAssets).not.toHaveBeenCalled();
            expect(result).toBe(zipBuffer);
        });
    });
});
