import { LiteralUnion } from 'type-fest';

/**
 * TypeScript interface for @semantic-release/changelog plugin configuration.
 *
 * This plugin creates or updates a changelog file.
 *
 * @see https://github.com/semantic-release/changelog
 */
/**
 * Configuration for @semantic-release/changelog plugin.
 */
interface ChangelogConfig {
    /**
     * File path to create or update the changelog.
     *
     * @default 'CHANGELOG.md'
     */
    changelogFile?: string;
    /**
     * Title for the changelog file.
     *
     * @default '# Changelog'
     */
    changelogTitle?: string;
    /**
     * Additional options that might be used by future versions.
     */
    [key: string]: unknown;
}

/**
 * TypeScript interface for @semantic-release/commit-analyzer plugin configuration.
 *
 * This plugin determines the type of release based on commit messages.
 *
 * @see https://github.com/semantic-release/commit-analyzer
 */

/**
 * Rule for determining release type based on commit properties.
 */
interface ReleaseRule {
    /**
     * The commit type (e.g., 'feat', 'fix', 'docs').
     */
    type?: string;
    /**
     * The commit scope.
     */
    scope?: string;
    /**
     * The subject of the commit.
     */
    subject?: string;
    /**
     * The release type to trigger (major, minor, patch, or false for no release).
     */
    release: 'major' | 'minor' | 'patch' | false;
    /**
     * Additional properties for matching commits.
     */
    [key: string]: unknown;
}
/**
 * Parser options for conventional-commits-parser.
 */
interface ParserOptions {
    /**
     * Keywords to identify breaking changes.
     *
     * @default ['BREAKING CHANGE', 'BREAKING CHANGES']
     */
    noteKeywords?: string[];
    /**
     * Pattern for parsing commit header.
     */
    headerPattern?: RegExp;
    /**
     * Correspondence between commit header and parsed values.
     */
    headerCorrespondence?: string[];
    /**
     * Pattern for parsing references in commit message.
     */
    referenceActions?: string[];
    /**
     * Whether to include the merge commits.
     */
    mergePattern?: RegExp;
    /**
     * Correspondence for merge commits.
     */
    mergeCorrespondence?: string[];
    /**
     * Pattern for parsing revert commits.
     */
    revertPattern?: RegExp;
    /**
     * Correspondence for revert commits.
     */
    revertCorrespondence?: string[];
    /**
     * Field names to include in parsed commit.
     */
    fieldPattern?: RegExp;
    /**
     * Whether to warn about malformed commits.
     */
    warn?: boolean;
    /**
     * Additional parser options.
     */
    [key: string]: unknown;
}
/**
 * Configuration for @semantic-release/commit-analyzer plugin.
 */
interface CommitAnalyzerConfig {
    /**
     * Conventional-changelog preset name.
     *
     * @default 'angular'
     */
    preset?: LiteralUnion<'angular' | 'atom' | 'codemirror' | 'ember' | 'eslint' | 'express' | 'jquery' | 'jshint' | 'conventionalcommits', string>;
    /**
     * npm package name of a custom conventional-changelog preset.
     * Cannot be used together with 'preset'.
     */
    config?: string;
    /**
     * Additional conventional-commits-parser options.
     * Extends the ones loaded by preset or config.
     */
    parserOpts?: ParserOptions;
    /**
     * External module, path to a module, or array of rules for determining release type.
     *
     * Rules are checked in order, and the first matching rule determines the release type.
     */
    releaseRules?: string | ReleaseRule[];
    /**
     * Additional configuration passed to the conventional-changelog preset.
     * Used for example with conventional-changelog-conventionalcommits.
     */
    presetConfig?: Record<string, unknown>;
    /**
     * Additional options that might be used by future versions or custom presets.
     */
    [key: string]: unknown;
}

/**
 * TypeScript interface for @semantic-release/git plugin configuration.
 *
 * This plugin commits files to the Git repository during the prepare step.
 *
 * @see https://github.com/semantic-release/git
 */
/**
 * Configuration for @semantic-release/git plugin.
 */
interface GitConfig {
    /**
     * Files to commit to the Git repository.
     * Can include glob patterns.
     *
     * @default ['CHANGELOG.md', 'package.json', 'package-lock.json', 'npm-shrinkwrap.json']
     */
    assets?: string | string[];
    /**
     * Commit message template.
     *
     * @default 'chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}'
     */
    message?: string;
    /**
     * Additional options that might be used by future versions.
     */
    [key: string]: unknown;
}

/**
 * TypeScript interface for @semantic-release/github plugin configuration.
 *
 * This plugin publishes GitHub releases and verifies GitHub authentication.
 *
 * @see https://github.com/semantic-release/github
 */
/**
 * Asset configuration for GitHub releases.
 */
interface GithubAsset {
    /**
     * Path to the asset file(s). Can include glob patterns.
     */
    path: string;
    /**
     * Name of the asset in the GitHub release.
     */
    name?: string;
    /**
     * Label for the asset in the GitHub release.
     */
    label?: string;
}
/**
 * Configuration for @semantic-release/github plugin.
 */
interface GithubConfig {
    /**
     * GitHub API URL.
     *
     * @default 'https://api.github.com'
     */
    githubUrl?: string;
    /**
     * GitHub API endpoint path prefix.
     *
     * @default '/api/v3'
     */
    githubApiPathPrefix?: string;
    /**
     * Proxy URL for GitHub API requests.
     */
    proxy?: string;
    /**
     * Assets to upload to the GitHub release.
     * Can be a string (glob pattern), array of strings, or array of asset objects.
     */
    assets?: string | string[] | GithubAsset[];
    /**
     * Labels to add to pull requests and issues.
     */
    labels?: string[];
    /**
     * Template for the GitHub release name.
     *
     * @default '${nextRelease.gitTag}'
     */
    releasedLabels?: string[];
    /**
     * Comment on resolved issues and merged pull requests.
     *
     * @default true
     */
    addReleases?: 'bottom' | 'top' | false;
    /**
     * Draft release instead of publishing immediately.
     *
     * @default false
     */
    draft?: boolean;
    /**
     * Template for issue and pull request comments.
     */
    successComment?: string | false;
    /**
     * Template for issue comments when a release fails.
     */
    failComment?: string | false;
    /**
     * Template for the release title.
     */
    failTitle?: string;
    /**
     * Template for issue labels when a release fails.
     */
    failLabels?: string[];
    /**
     * Template for discussion category when a release is published.
     */
    discussionCategoryName?: string;
    /**
     * Additional options that might be used by future versions.
     */
    [key: string]: unknown;
}

/**
 * TypeScript interface for @semantic-release/npm plugin configuration.
 *
 * This plugin publishes npm packages and verifies npm registry authentication.
 *
 * @see https://github.com/semantic-release/npm
 */

/**
 * Configuration for @semantic-release/npm plugin.
 */
interface NpmConfig {
    /**
     * Directory path to publish.
     *
     * @default '.'
     */
    pkgRoot?: string;
    /**
     * Whether to publish the package to the npm registry.
     *
     * @default true
     */
    npmPublish?: boolean;
    /**
     * The npm tag to publish to.
     *
     * @default 'latest' for regular releases, or the prerelease identifier for prerelease versions
     */
    tarballDir?: string;
    /**
     * Additional options that might be used by future versions.
     */
    [key: string]: unknown;
}

/**
 * TypeScript interface for @semantic-release/release-notes-generator plugin configuration.
 *
 * This plugin generates release notes based on commit messages.
 *
 * @see https://github.com/semantic-release/release-notes-generator
 */

/**
 * Writer options for customizing the release notes output.
 */
interface WriterOptions {
    /**
     * Main template for the release notes.
     */
    mainTemplate?: string;
    /**
     * Template for each commit group.
     */
    commitGroupsTemplate?: string;
    /**
     * Template for each commit.
     */
    commitTemplate?: string;
    /**
     * Template for the header.
     */
    headerTemplate?: string;
    /**
     * Template for the footer.
     */
    footerTemplate?: string;
    /**
     * How to group commits.
     */
    groupBy?: string;
    /**
     * How to sort commit groups.
     */
    commitGroupsSort?: string | ((a: unknown, b: unknown) => number);
    /**
     * How to sort commits within groups.
     */
    commitsSort?: string | string[] | ((a: unknown, b: unknown) => number);
    /**
     * How to sort notes within commits.
     */
    noteGroupsSort?: string | ((a: unknown, b: unknown) => number);
    /**
     * How to sort notes.
     */
    notesSort?: string | ((a: unknown, b: unknown) => number);
    /**
     * Transform function for commits.
     */
    transform?: (commit: unknown, context: unknown) => unknown;
    /**
     * Additional writer options.
     */
    [key: string]: unknown;
}
/**
 * Configuration for @semantic-release/release-notes-generator plugin.
 */
interface ReleaseNotesGeneratorConfig {
    /**
     * Conventional-changelog preset name.
     *
     * @default 'angular'
     */
    preset?: LiteralUnion<'angular' | 'atom' | 'codemirror' | 'ember' | 'eslint' | 'express' | 'jquery' | 'jshint' | 'conventionalcommits', string>;
    /**
     * npm package name of a custom conventional-changelog preset.
     * Cannot be used together with 'preset'.
     */
    config?: string;
    /**
     * Additional conventional-commits-parser options.
     */
    parserOpts?: {
        /**
         * Keywords to identify breaking changes.
         */
        noteKeywords?: string[];
        /**
         * Additional parser options.
         */
        [key: string]: unknown;
    };
    /**
     * Additional conventional-changelog-writer options.
     */
    writerOpts?: WriterOptions;
    /**
     * Additional configuration passed to the conventional-changelog preset.
     */
    presetConfig?: Record<string, unknown>;
    /**
     * Path to a Handlebars template file for customizing the release notes.
     */
    linkCompare?: boolean;
    /**
     * Whether to include references in the release notes.
     */
    linkReferences?: boolean;
    /**
     * Additional options that might be used by future versions.
     */
    [key: string]: unknown;
}

export type { CommitAnalyzerConfig as C, GithubConfig as G, NpmConfig as N, ReleaseNotesGeneratorConfig as R, ChangelogConfig as a, GitConfig as b };
