<?php


namespace Mainto\RpcServer\Util;


use stdClass;

class Language {
    public static array $simpleType = [
        'bool',
        'int',
        'string',
        'float',
        'array',
    ];

    public static array $simpleTypeMap = [
        'bool'    => 'bool',
        'boolean' => 'bool',
        'integer' => 'int',
        'int'     => 'int',
        'string'  => 'string',
        'float'   => 'float',
        'array'   => 'array',
    ];

    public static array $rpcTypeMap = [
        "string"         => "string",
        "uint"           => "int",
        "int"            => "int",
        "double"         => "float",
        "unsignedDouble" => "float",
        "bool"           => "bool",
        "array"          => "array",
        "array<int>"     => "array",
        "array<uint>"    => "array",
        "array<string>"  => "array",
    ];

    /**
     * @var stdClass
     */
    public static stdClass $placeholder;

    public static function init () {
        self::$placeholder = new stdClass();
    }

    /**
     * 类型修复
     *
     * @param $value
     * @param $type
     * @return bool
     */
    public static function tryAutoFixType (&$value, $type): bool {
        switch ($type) {
            case "string":
                if (is_string($value)) {
                    $value = strval($value);
                    return true;
                }
                return false;
            case "uint":
                if (is_numeric($value) && $value >= 0) {
                    $value = intval($value);
                    return true;
                }
                return false;
            case "int":
                if (is_numeric($value)) {
                    $value = intval($value);
                    return true;
                }
                return false;
            case "double":
                if (is_numeric($value)) {
                    $value = floatval($value);
                    return true;
                }
                return false;
            case "unsignedDouble":
                if (is_numeric($value) && $value >= 0) {
                    $value = floatval($value);
                    return true;
                }
                return false;
            case "bool":
                if (is_bool($value)) {
                    return true;
                } else {
                    if (is_string($value) || is_numeric($value)) {
                        switch (strtolower($value)) {
                            case 'true':
                            case 1:
                                $value = true;
                                return true;
                            case 'false':
                            case 0:
                                $value = false;
                                return true;
                        }
                    }
                    return false;
                }
            case "array":
                return is_array($value);
            case "array<int>":
                if (is_array($value)) {
                    foreach ($value as $key => $val) {
                        $value[$key] = (int)$val;
                    }
                    return true;
                }
                return false;
            case  "array<uint>":
                if (is_array($value)) {
                    foreach ($value as $key => $val) {
                        $val = (int)$val;
                        if ($val < 0) return false;

                        $value[$key] = (int)$val;
                    }
                    return true;
                }
                return false;
            case  "array<string>":
                if (is_array($value)) {
                    foreach ($value as $key => $val) {
                        $value[$key] = (string)$val;
                    }
                    return true;
                }
                return false;
            case "mixed":
                return true;
        }

        return true;
    }
}