#compdef periphery

__periphery_complete() {
    local -ar non_empty_completions=("${@:#(|:*)}")
    local -ar empty_completions=("${(M)@:#(|:*)}")
    _describe -V '' non_empty_completions -- empty_completions -P $'\'\''
}

__periphery_custom_complete() {
    local -a completions
    completions=("${(@f)"$("${command_name}" "${@}" "${command_line[@]}")"}")
    if [[ "${#completions[@]}" -gt 1 ]]; then
        __periphery_complete "${completions[@]:0:-1}"
    fi
}

__periphery_cursor_index_in_current_word() {
    if [[ -z "${QIPREFIX}${IPREFIX}${PREFIX}" ]]; then
        printf 0
    else
        printf %s "${#${(z)LBUFFER}[-1]}"
    fi
}

_periphery() {
    emulate -RL zsh -G
    setopt extendedglob nullglob numericglobsort
    unsetopt aliases banghist

    local -xr SAP_SHELL=zsh
    local -x SAP_SHELL_VERSION
    SAP_SHELL_VERSION="$(builtin emulate zsh -c 'printf %s "${ZSH_VERSION}"')"
    local -r SAP_SHELL_VERSION

    local context state state_descr line
    local -A opt_args

    local -r command_name="${words[1]}"
    local -ar command_line=("${words[@]}")
    local -ir current_word_index="$((CURRENT - 1))"

    local -i ret=1
    local -ar arg_specs=(
        '(-h --help)'{-h,--help}'[Show help information.]'
        '(-): :->command'
        '(-)*:: :->arg'
    )
    _arguments -w -s -S : "${arg_specs[@]}" && ret=0
    case "${state}" in
    command)
        local -ar subcommands=(
            'scan:Scan for unused code'
            'check-update:Check for available update'
            'clear-cache:Clear Periphery'\''s build cache'
            'version:Display the version of Periphery'
            'help:Show subcommand help information.'
        )
        _describe -V subcommand subcommands && ret=0
        ;;
    arg)
        case "${words[1]}" in
        scan|check-update|clear-cache|version|help)
            "_periphery_${words[1]}" && ret=0
            ;;
        esac
        ;;
    esac

    return "${ret}"
}

_periphery_scan() {
    local -i ret=1
    local -ar ___format=('xcode' 'csv' 'json' 'checkstyle' 'codeclimate' 'github-actions' 'github-markdown' 'gitlab-codequality')
    local -ar ___color=('auto' 'always' 'never')
    local -ar arg_specs=(
        '*:build-arguments:'
        '--setup[Enable guided setup]'
        '--project-root[Path to the root directory of your project]:project-root:'
        '--config[Path to configuration file. By default Periphery will look for .periphery.yml in the current directory]:config:'
        '--project[Path to your project'\''s .xcodeproj or .xcworkspace]:project:'
        '--schemes[Schemes to build. All targets built by these schemes will be scanned]:schemes:'
        '--format[Output format]:format:{__periphery_complete "${___format[@]}"}'
        '--exclude-tests[Exclude test targets from indexing]'
        '--exclude-targets[Targets to exclude from indexing]:exclude-targets:'
        '--index-exclude[Source file globs to exclude from indexing]:index-exclude:'
        '--report-exclude[Source file globs to exclude from the results. Note that this option is purely cosmetic, these files will still be indexed]:report-exclude:'
        '--report-include[Source file globs to include in the results. This option supersedes '\''--report-exclude'\''. Note that this option is purely cosmetic, these files will still be indexed]:report-include:'
        '--retain-files[Source file globs for which all containing declarations will be retained]:retain-files:'
        '--index-store-path[Index store paths. Implies '\''--skip-build'\'']:index-store-path:'
        '--retain-public[Retain all public declarations, recommended for framework/library projects]'
        '--no-retain-spi[Public SPIs (System Programming Interfaces) to check for unused code even when '\''--retain-public'\'' is enabled]:no-retain-spi:'
        '--disable-redundant-public-analysis[Disable identification of redundant public accessibility]'
        '--disable-unused-import-analysis[Disable identification of unused imports]'
        '--superfluous-ignore-comments[Report superfluous ignore comments]'
        '--no-superfluous-ignore-comments[Report superfluous ignore comments]'
        '--retain-unused-imported-modules[Names of unused imported modules to retain]:retain-unused-imported-modules:'
        '--retain-assign-only-properties[Retain properties that are assigned, but never used]'
        '--retain-assign-only-property-types[Property types to retain if the property is assigned, but never read]:retain-assign-only-property-types:'
        '--external-encodable-protocols[Names of external protocols that inherit Encodable. Properties and CodingKey enums of types conforming to these protocols will be retained]:external-encodable-protocols:'
        '--external-codable-protocols[Names of external protocols that inherit Codable. Properties and CodingKey enums of types conforming to these protocols will be retained]:external-codable-protocols:'
        '--external-test-case-classes[Names of XCTestCase subclasses that reside in external targets]:external-test-case-classes:'
        '--retain-objc-accessible[Retain declarations that are exposed to Objective-C implicitly by inheriting NSObject classes, or explicitly with the @objc and @objcMembers attributes]'
        '--retain-objc-annotated[Retain declarations that are exposed to Objective-C explicitly with the @objc and @objcMembers attributes]'
        '--retain-unused-protocol-func-params[Retain unused protocol function parameters, even if the parameter is unused in all conforming functions]'
        '--retain-swift-ui-previews[Retain SwiftUI previews]'
        '--retain-codable-properties[Retain properties on Codable types (including Encodable and Decodable)]'
        '--retain-encodable-properties[Retain properties on Encodable types only]'
        '--clean-build[Clean existing build artifacts before building]'
        '--skip-build[Skip the project build step]'
        '--skip-schemes-validation[Skip schemes validation]'
        '--relative-results[Output result paths relative to the current directory]'
        '--strict[Exit with non-zero status if any unused code is found]'
        '--disable-update-check[Disable checking for updates]'
        '--verbose[Enable verbose logging]'
        '--quiet[Only output results]'
        '--color[Colored output mode]:color:{__periphery_complete "${___color[@]}"}'
        '--json-package-manifest-path[JSON package manifest path (obtained using `swift package describe --type json` or manually)]:json-package-manifest-path:'
        '--baseline[Baseline file path used to filter results]:baseline:'
        '--write-baseline[Baseline file path where results are written. Pass the same path to '\''--baseline'\'' in subsequent scans to exclude the results recorded in the baseline.]:write-baseline:'
        '--write-results[File path where formatted results are written.]:write-results:'
        '--generic-project-config[Project configuration for non-Apple build systems]:generic-project-config:'
        '--bazel[Enable Bazel project mode]'
        '--bazel-filter[Filter pattern applied to the Bazel top-level targets query]:bazel-filter:'
        '--bazel-index-store[Path to a global index store populated by Bazel. If provided, will be used instead of individual module stores.]:bazel-index-store:'
        '--bazel-check-visibility[Enable Bazel visibility checking]'
        '(-h --help)'{-h,--help}'[Show help information.]'
    )
    _arguments -w -s -S : "${arg_specs[@]}" && ret=0

    return "${ret}"
}

_periphery_check-update() {
    local -i ret=1
    local -ar arg_specs=(
        '(-h --help)'{-h,--help}'[Show help information.]'
    )
    _arguments -w -s -S : "${arg_specs[@]}" && ret=0

    return "${ret}"
}

_periphery_clear-cache() {
    local -i ret=1
    local -ar arg_specs=(
        '(-h --help)'{-h,--help}'[Show help information.]'
    )
    _arguments -w -s -S : "${arg_specs[@]}" && ret=0

    return "${ret}"
}

_periphery_version() {
    local -i ret=1
    local -ar arg_specs=(
        '(-h --help)'{-h,--help}'[Show help information.]'
    )
    _arguments -w -s -S : "${arg_specs[@]}" && ret=0

    return "${ret}"
}

_periphery_help() {
    local -i ret=1
    local -ar arg_specs=(
        '*:subcommands:'
    )
    _arguments -w -s -S : "${arg_specs[@]}" && ret=0

    return "${ret}"
}

if [[ "${funcstack[1]}" = _periphery ]]; then
    _periphery "${@}"
else
    compdef _periphery periphery
fi
