import { IReplaceOptions } from '../contracts';
import { footerReplaceBelowMarker } from '../write-markdown.constants';
import { splitContent, findEscapeSequence, filterDoubleBlankLines } from './line-ending.helper';

/**
 * Adds or replaces content between 2 markers within a text string
 * @param inputString
 * @param content
 * @param options
 * @returns
 */
export function addContent(inputString: string, content: string | string[], options: IReplaceOptions): string {
    const replaceBelow = options?.replaceBelow;
    const replaceAbove = options?.replaceAbove;
    content = Array.isArray(content) ? content : [content];

    const lineBreak = findEscapeSequence(inputString);
    const lines = splitContent(inputString);
    const replaceBelowLine =
        replaceBelow != null ? lines.filter((line) => line.indexOf(replaceBelow) === 0)[0] : undefined;
    const replaceBelowIndex = replaceBelowLine != null ? lines.indexOf(replaceBelowLine) : -1;
    const replaceAboveLine =
        replaceAbove != null ? lines.filter((line) => line.indexOf(replaceAbove) === 0)[0] : undefined;
    const replaceAboveIndex = replaceAboveLine != null ? lines.indexOf(replaceAboveLine) : -1;

    if (replaceAboveIndex > -1 && replaceBelowIndex > -1 && replaceAboveIndex < replaceBelowIndex) {
        throw new Error(
            `The replaceAbove marker '${options.replaceAbove}' was found before the replaceBelow marker '${options.replaceBelow}'. The replaceBelow marked must be before the replaceAbove.`,
        );
    }

    const linesBefore = lines.slice(0, replaceBelowIndex + 1);
    const linesAfter = replaceAboveIndex >= 0 ? lines.slice(replaceAboveIndex) : [];

    const contentLines = content.reduce(
        (lines, currentContent) => [...lines, ...splitContent(currentContent)],
        new Array<string>(),
    );

    let allLines = [...linesBefore, ...contentLines, ...linesAfter];

    if (options.removeDoubleBlankLines) {
        allLines = allLines.filter((line, index, lines) => filterDoubleBlankLines(line, index, lines));
    }

    return allLines.join(lineBreak);
}

export function addCommandLineArgsFooter(fileContent: string): string {
    if (fileContent.indexOf(footerReplaceBelowMarker) < 0) {
        fileContent = `${fileContent}  

${footerReplaceBelowMarker}`;
    }

    const footerContent = `Markdown Generated by [ts-command-line-args](https://www.npmjs.com/package/ts-command-line-args)`;

    return addContent(fileContent, footerContent, {
        replaceBelow: footerReplaceBelowMarker,
        removeDoubleBlankLines: false,
    });
}
