<?php
/**
 * Utility functions for wp cli commands
 */
abstract class Loco_cli_Utils {


    /**
     * Collect translation sets according to type/domain filter
     * @return Loco_package_Project[]
     */
    public static function collectProjects( $filter ):array {
        $projects = [];
        $domain = null;
        $slug = null;
        // bundle type filter, with optional argument
        if( preg_match('/^(plugins|themes|core)(?::(.+))?/i',$filter,$matched) ){
            $type = strtolower($matched[1]);
            $handle = isset($matched[2]) ? $matched[2] : '';
            if( 'plugins' === $type ){
                if( $handle ){
                    $bundles = [ Loco_package_Plugin::create($handle) ];
                }
                else {
                    $bundles = Loco_package_Plugin::getAll();
                }
            }
            else if( 'themes' === $type ){
                if( $handle ){
                    $bundles = [ Loco_package_Theme::create($handle) ];
                }
                else {
                    $bundles = Loco_package_Theme::getAll();
                }
            }
            else {
                $bundles = [ Loco_package_Core::create() ];
                $slug = $handle;
            }
        }
        // else fall back to text domain filter
        else {
            $domain = $filter;
            $bundles = [ Loco_package_Core::create() ];
            $bundles = array_merge( $bundles, Loco_package_Plugin::getAll() );
            $bundles = array_merge( $bundles, Loco_package_Theme::getAll() );
        }
        /* @var Loco_package_Project $project */
        foreach( $bundles as $bundle ){
            foreach( $bundle as $project ){
                if( $domain && $project->getDomain()->getName() !== $domain ){
                    continue;
                }
                if( $slug && $project->getSlug() !== $slug ){
                    continue;
                }
                $projects[] = $project;
            }
        }
        if( ! $projects ){
            throw new Loco_error_Exception('No translation sets found');
        }
        return $projects;
    }


    /**
     * Collect locales from one or more language tags
     * @param string zero or more language tags
     * @return Loco_Locale[]
     */
    public static function collectLocales( $tags ){
        $locales = [];
        if( '' !== $tags ){
            $api = new Loco_api_WordPressTranslations;
            foreach( preg_split('/[\\s,;]+/i',$tags,-1,PREG_SPLIT_NO_EMPTY) as $tag ){
                $locale = Loco_Locale::parse($tag);
                if( ! $locale->isValid() ){
                    throw new Loco_error_Exception('Invalid locale: '.json_encode($tag) );
                }
                // TODO could expand language-only tags to known WordPress locales e.g. fr -> fr_FR
                $locales[ (string) $locale ] = $locale;
                $locale->ensureName($api);
            }
            // empty locales means ALL locales, so refuse to return ALL when filter was non-empty
            if( 0 === count($locales) ){
                throw new Loco_error_Exception('No valid locales in: '.json_encode($tags) );
            }
        }
        return $locales;
    }


    /**
     * Simple space-padded table
     * @param string[][] data rows to print
     */
    public static function tabulate( array $t ){
        $w = [];
        foreach( $t as $y => $row ){
            foreach( $row as $x => $value ){
                $width = mb_strlen($value,'UTF-8');
                $w[$x] = isset($w[$x]) ? max($w[$x],$width) : $width;
            }
        }
        foreach( $t as $y => $row ){
            $line = [];
            foreach( $w as $x => $width ){
                $value = isset($row[$x]) ? $row[$x] : '';
                $value = str_pad($value,$width,' ',STR_PAD_RIGHT);
                $line[] = $value;
            }
            self::debug( implode(' ',$line) );
        }
    }


    /**
     * Prints file listing to stdout
     */
    public static function tabulateFiles(){
        $t = [];
        /* @var Loco_fs_File $file */
        foreach( func_get_args() as $file ){
            if( $file instanceof Loco_fs_File && $file->exists() ){
                $f = new Loco_mvc_FileParams([],$file);
                $t[] = [ $f->owner, $f->group, $f->smode, $f->relpath ];
            }
        }
        self::tabulate($t);
    }


    /**
     * WP_CLI debug logger
     */
    public static function debug(){
        $args = func_get_args();
        $message = array_shift($args);
        if( $args ){
            $message = vsprintf($message,$args);
        }
        WP_CLI::debug( $message,'loco' );
    }
    
    
    /**
     * Parse boolean command line option. Absence is equal to false
     * @param string[]
     * @param string
     * @return bool
     */
    public static function bool( array $opts, $key ){
        $value = isset($opts[$key]) ? $opts[$key] : false;
        if( ! is_bool($value) ){
            $value = $value && 'false' !== $value & 'no' !== $value;
        }
        return $value;
    }

} 