using Gee;

public class PhpToValaClassModel : Object {
    private PhpToValaTranspiler transpiler;

    public PhpToValaClassModel (PhpToValaTranspiler transpiler) {
        this.transpiler = transpiler;
    }

    public PhpClass? find_php_class (string class_name) {
        PhpClass? php_class = transpiler.php_classes[class_name];
        if (php_class == null) {
            php_class = transpiler.external_php_classes[class_name];
        }
        return php_class;
    }

    public LocalFunction? find_class_method (string class_name, string method_name) {
        PhpClass? php_class = find_php_class (class_name);
        return find_class_method_in_class (php_class, method_name);
    }

    private LocalFunction? find_class_method_in_class (PhpClass? php_class, string method_name) {
        if (php_class == null) {
            return null;
        }
        foreach (LocalFunction method in php_class.methods) {
            if (method.name == method_name) {
                return method;
            }
        }
        if (php_class.extends_name != "") {
            PhpClass? parent = transpiler.php_classes[php_class.extends_name];
            if (parent == null) {
                parent = transpiler.external_php_classes[php_class.extends_name];
            }
            if (parent == null) {
                parent = transpiler.external_php_classes[resolve_relative_php_class_name (php_class, php_class.extends_name)];
            }
            return find_class_method_in_class (parent, method_name);
        }
        return null;
    }

    private string resolve_relative_php_class_name (PhpClass php_class, string relative_name) {
        foreach (string key in transpiler.external_php_classes.keys) {
            if (transpiler.external_php_classes[key] == php_class) {
                int slash = key.last_index_of ("\\");
                if (slash > 0) {
                    return key.substring (0, slash + 1) + relative_name;
                }
            }
        }
        return relative_name;
    }

    public bool class_exists (string class_name) {
        return transpiler.php_classes.has_key (class_name) || transpiler.external_php_classes.has_key (class_name);
    }
}
