PSCompletions.psm1

<#
# @Author : abgox
# @Github : https://github.com/abgox/PSCompletions
#>


. $PSScriptRoot\core\replace.ps1
function PSCompletions {
    $arg = $args
    function _templete($list) {
        foreach ($_ in $list) {
            $res += ' ' + $_
        }
        return ("`n" + ' ' + $_psc.config.root_cmd + ' ' + $arg[0] + $res)
    }
    function param_error($err, $completion = 'scoop', $example2 = (_templete @('scoop volta ...'))) {
        if ($err -eq 'min') {
            $res = $_psc.json.param_min
        }
        else {
            $res = $_psc.json.param_max
        }
        Write-Host (psc_replace $res) -f Red
    }

    function _list {
        if ($arg.Length -gt 1) {
            param_error 'max' '' ''
            return
        }
        $data = New-Object System.Collections.ArrayList
        foreach ($_ in $_psc.installed.baseName) {
            $alias = _psc_get_cmd ($_psc.completions + '\' + $_) $_
            if ($alias -eq $_) { $alias = '' }
            $data += [PSCustomObject]@{
                Completion = $_
                Alias      = $alias
            }
        }
        $data | Format-Table -AutoSize -Wrap
        Write-Host (psc_replace $_psc.json.alias_tip) -f Yellow
    }
    function _Add {
        if ($arg.Length -lt 2) {
            param_error 'min'
            return
        }
        _psc_download_list
        $list = $arg[1..($arg.Length - 1)]
        foreach ($_ in $list) {
            if ($_ -in $_psc.list) {
                _psc_add_completion $_
            }
            else {
                Write-Host (psc_replace $_psc.json.add_error) -f Red
            }
        }
    }
    function _Remove {
        if ($arg.Length -lt 2) {
            param_error 'min'
            return
        }
        $list = $arg[1..($arg.Length - 1)]
        foreach ($_ in $list) {
            if ($_ -in $_psc.installed.BaseName) {
                $dir = $PSScriptRoot + '\completions\' + $_
                rmdir $dir -Recurse -Force
                if (!(Test-Path($dir))) {
                    Write-Host (psc_replace $_psc.json.rm_completed) -f Green
                }
            }
            else {
                Write-Host (psc_replace $_psc.json.rm_error) -f Red
            }
        }
    }
    function _Update {
        function _do {
            $res = New-Object System.Collections.ArrayList
            foreach ($_ in $_psc.installed.BaseName) {
                $url = $_psc.url + '/completions/' + $_ + '/.guid'
                $response = Invoke-WebRequest -Uri  $url
                if ($response.StatusCode -eq 200) {
                    $content = ($response.Content).Trim()
                    $guid = (_psc_get_content ($_psc.completions + '\' + $_ + '\.guid')).Trim()
                    if ($guid -ne $content) { $res.Add($_) > $null }
                }
            }
            echo $res > $_psc.update_path
            $_psc.update = _psc_get_content $_psc.update_path
            Write-Host '----------' -f Cyan
            if ($res) {
                Write-Host (psc_replace $_psc.json.update_can) -f Yellow
                Write-Host (psc_replace $_psc.update) -f Green
            }
            else {
                Write-Host (psc_replace $_psc.json.update_no) -f Green
            }
        }
        if ($arg.Length -eq 1) {
            _do
        }
        else {
            if ($arg[1] -eq '*') {
                foreach ($_ in $_psc.update) {
                    _psc_add_completion $_ $true $true
                }
            }
            else {
                $list = $arg[1..($arg.Length - 1)]
                foreach ($_ in $list) {
                    if ($_ -in $_psc.installed.BaseName) {
                        _psc_add_completion $_ $true $true
                    }
                    else {
                        Write-Host (psc_replace $_psc.json.update_error) -f Red
                    }
                }
            }
            _do
        }
    }

    function _Search {
        if ($arg.Length -lt 2) {
            param_error 'min' 'scoop' ''
            return
        }
        elseif ($arg.Length -gt 2) {
            param_error 'max' 'scoop' ''
            return
        }
        Write-Host (psc_replace ($_psc.json.search + $arg[1] + ' ...')) -f Yellow
        _psc_download_list

        foreach ( $_ in $_psc.list) {
            if ( $_ -like ($arg[1])) {
                Write-Host $_ -f green
            }
        }
    }

    function _Which {
        if ($arg.Length -lt 2) {
            param_error 'min'
            return
        }
        $list = $arg[1..($arg.Length - 1)]
        foreach ($_ in $list) {
            if ($_ -in $_psc.installed.BaseName) {
                echo ($_psc.completions + '\' + $_)
            }
            else {
                Write-Host (psc_replace $_psc.json.which_error) -f Red
            }
        }
    }

    function _alias {
        $cmd_list = @('add', 'rm', 'list', 'reset')
        if ($arg.Length -eq 1) {
            param_error 'min' '<list|add|rm|reset> [Compleiton...]' ((_templete @($arg[0], 'add', 'scoop', 'volta', '...')) + (_templete @($arg[0], 'rm', 'scoop', 'volta', '...')) + (_templete @($arg[0], 'list')) + (_templete @($arg, 'reset')))
            return
        }
        if ($arg[1] -notin $cmd_list) {
            Write-Host (psc_replace $_psc.json.param_error) -f Red
            return
        }
        function check_add_cm($value, $num, $num2) {
            if ($arg[1] -eq $value) {
                function _do($v) {
                    param_error $v ($value + ' <Completion> <Alias>') (_templete @($arg[0], $value, 'scoop', 'sco'))
                }
                if ($arg.Length -lt $num) {
                    _do 'min'
                    return $true
                }
                elseif ($arg.Length -gt $num2) {
                    _do 'max'
                    return $true
                }
            }
            return $false
        }
        if (check_add_cm 'add' 4 4) { return }
        if (check_add_cm 'rm' 3 999) { return }

        if ($arg.Length -gt 2) {
            if ($arg[1] -eq 'list') {
                param_error 'max' 'list' ''
                return
            }
            elseif ($arg[1] -eq 'reset') {
                param_error 'max' 'reset' ''
                return
            }
        }
        $list = Get-ChildItem -Path ($_psc.root_dir + '\completions') -Filter ".alias" -Recurse
        if ($arg[1] -eq 'list') {
            $data = New-Object System.Collections.ArrayList
            foreach ($_ in $list) {
                $cmd_old = Split-Path (Split-Path $_.FullName -Parent) -Leaf
                $data += [PSCustomObject]@{
                    Command = $cmd_old
                    Alias   = _psc_get_content $_.FullName
                }
            }
            $data | Format-Table -AutoSize -Wrap
            Write-Host (psc_replace $_psc.json.alias_tip) -f Yellow
            return
        }
        elseif ($arg[1] -eq 'add') {
            if ($arg[2] -in $_psc.installed.baseName) {
                echo $arg[3] > ($_psc.completions + '\' + $arg[2] + '\.alias')
                Write-Host (psc_replace $_psc.json.alias_add) -f Green
            }
            else {
                Write-Host (psc_replace $_psc.json.alias_error) -f Red
            }
        }
        elseif ($arg[1] -eq 'rm') {
            $rm_list = $arg[2..($arg.Length - 1)]
            $del_list = ''
            foreach ($_ in $list) {
                $cmd = Split-Path (Split-Path $_.FullName -Parent) -Leaf
                $alias = _psc_get_content $_.FullName
                if ($alias -in $rm_list) {
                    $del_list += $alias + '(' + $cmd + ')' + ' '
                    rm $_.FullName -Force
                }
            }
            if ($del_list) {
                Write-Host (psc_replace $_psc.json.alias_del) -f Green
            }
            else {
                Write-Host (psc_replace ($_psc.json.alias_rm_error)) -f Red
            }

        }
        else {
            Write-Host (psc_replace $_psc.json.reset_confirm) -f Yellow
            Read-Host (psc_replace $_psc.json.confirm)
            $del_list = ''
            foreach ($_ in $list) {
                $cmd_old = Split-Path (Split-Path $_.FullName -Parent) -Leaf
                $alias = _psc_get_content $_.FullName
                $del_list += $alias + '(' + $cmd_old + ')' + ' '
                rm $_.FullName -Force
            }
            _psc_set_config 'root_cmd' 'psc'
            if ($del_list) {
                Write-Host (psc_replace (psc_replace $_psc.json.alias_reset)) -f Green
            }
        }
    }

    function _Config {
        function _do($value) {
            param_error $value 'language en-US' (_templete @($arg[0], 'root_cmd', 'p'))
        }
        if ($arg.Length -lt 2) {
            _do 'min'
            return
        }
        elseif ($arg.Length -gt 3) {
            _do 'max'
            return
        }
        if ($arg.Length -eq 2) {
            if ($arg[1] -in $_psc.config.Keys) {
                echo ($_psc.config[$arg[1]])
            }
            else {
                if ($arg[1] -eq 'reset') {
                    $module_version = $_psc.version
                    $root_cmd = 'psc'
                    echo $root_cmd > $_psc.alias_path
                    $github = 'https://github.com/abgox/PSCompletions'
                    $gitee = 'https://gitee.com/abgox/PSCompletions'
                    $language = (Get-WinSystemLocale).name
                    $update = 1
                    [environment]::SetEnvironmentvariable('abgox_PSCompletions', ($module_version + ';' + $root_cmd + ';' + $github + ';' + $gitee + ';' + $language + ';' + $update), 'User')
                    return
                }
                Write-Host (psc_replace $_psc.json.config_error) -f Red
            }
        }
        else {
            if ($arg[1] -in $_psc.config.Keys) {
                if ($arg[1] -eq 'root_cmd') {
                    echo $arg[2] > $_psc.alias_path
                }
                _psc_set_config $arg[1] $arg[2]
                Write-Host (psc_replace $_psc.json.config_completed) -f Green
            }
            else {
                Write-Host (psc_replace $_psc.json.config_error) -f Red
            }
        }
    }

    function _Help {
        Write-Host (psc_replace $_psc.json.description) -f DarkCyan
    }

    switch ($arg[0]) {
        'list' {
            _list
        }
        'add' {
            _Add
        }
        'rm' {
            _Remove
        }
        'update' {
            _Update
        }
        'search' {
            _Search
        }
        'which' {
            _Which
        }
        'alias' {
            _alias
        }
        'config' {
            _Config
        }
        default {
            if ($arg.Length -eq 1) {
                Write-Host (psc_replace $_psc.json.cmd_error) -f Red
            }
            else { _Help }
        }
    }
    psc_init
}