package org.chromium.devtools.jsdoc.checks;

import com.google.javascript.rhino.JSTypeExpression;
import com.google.javascript.rhino.Node;
import com.google.javascript.rhino.Token;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

public final class ProtoFollowsExtendsChecker extends ContextTrackingChecker {
    private static final String PROTO_PROPERTY_NAME = "__proto__";
    private static final Set<String> IGNORED_SUPER_TYPES = new HashSet<>();
    static {
        IGNORED_SUPER_TYPES.add("WebInspector.Object");
    }

    private final Set<TypeRecord> typesWithAssignedProto = new HashSet<>();
    private final Set<FunctionRecord> functionsMissingSuperCall = new HashSet<>();

    @Override
    protected void enterNode(Node node) {
        switch (node.getToken()) {
            case ASSIGN:
            case VAR:
                handleAssignment(node);
                break;
            case STRING_KEY:
                handleColonNode(node);
                break;
            case FUNCTION:
                enterFunction();
                break;
            case CALL:
                handleCall(node);
                break;
            default:
                break;
        }
    }

    private void handleCall(Node callNode) {
        FunctionRecord contextFunction = getState().getCurrentFunctionRecord();
        if (contextFunction == null || !contextFunction.isConstructor()
                || !functionsMissingSuperCall.contains(contextFunction)) {
            return;
        }
        String typeName = validSuperConstructorName(callNode);
        if (typeName == null) {
            return;
        }
        TypeRecord typeRecord = getState().typeRecordsByTypeName.get(contextFunction.name);
        if (typeRecord == null) {
            return;
        }
        JSTypeExpression extendedType = typeRecord.getExtendedType();
        // FIXME: Strip template parameters from the extendedType.
        if (extendedType == null
                || !typeName.equals(AstUtil.getAnnotationTypeString(extendedType))) {
            return;
        }
        functionsMissingSuperCall.remove(contextFunction);
    }

    private String validSuperConstructorName(Node callNode) {
        String callTarget = getContext().getNodeText(callNode.getFirstChild());
        int lastDotIndex = callTarget.lastIndexOf('.');
        if (lastDotIndex == -1) {
            return null;
        }
        String methodName = callTarget.substring(lastDotIndex + 1);
        if (!"call".equals(methodName) && !"apply".equals(methodName)) {
            return null;
        }
        List<Node> arguments = AstUtil.getArguments(callNode);
        if (arguments.isEmpty() || !"this".equals(getContext().getNodeText(arguments.get(0)))) {
            return null;
        }
        return callTarget.substring(0, lastDotIndex);
    }

    @Override
    protected void leaveNode(Node node) {
        if (node.getToken() == Token.SCRIPT) {
            checkFinished();
            return;
        }
        if (node.getToken() == Token.FUNCTION) {
            leaveFunction();
            return;
        }
    }

    private void enterFunction() {
        FunctionRecord function = getState().getCurrentFunctionRecord();
        JSTypeExpression extendedType = getExtendedTypeToCheck(function);
        if (extendedType == null) {
            return;
        }
        if (!IGNORED_SUPER_TYPES.contains(AstUtil.getAnnotationTypeString(extendedType))) {
            functionsMissingSuperCall.add(function);
        }
    }

    private void leaveFunction() {
        FunctionRecord function = getState().getCurrentFunctionRecord();
        if (!functionsMissingSuperCall.contains(function)) {
            return;
        }
        JSTypeExpression extendedType = getExtendedTypeToCheck(function);
        if (extendedType == null) {
            return;
        }
        String annotationTypeString = AstUtil.getAnnotationTypeString(extendedType);
        if (annotationTypeString.startsWith("HTML")) {
            return;
        }

        reportErrorAtNodeStart(AstUtil.getFunctionNameNode(function.functionNode),
                String.format("Type %s extends %s but does not properly invoke its constructor",
                        function.name, annotationTypeString));
    }

    private JSTypeExpression getExtendedTypeToCheck(FunctionRecord function) {
        if (!function.isConstructor() || function.name == null) {
            return null;
        }
        TypeRecord type = getState().typeRecordsByTypeName.get(function.name);
        if (type == null || type.isInterface()) {
            return null;
        }
        return type.getExtendedType();
    }

    private void checkFinished() {
        for (TypeRecord record : getState().getTypeRecordsByTypeName().values()) {
            if (record.isInterface() || typesWithAssignedProto.contains(record)) {
                continue;
            }
            JSTypeExpression extendedType = record.getExtendedType();
            if (extendedType != null) {
                Node rootNode = extendedType.getRoot();
                if (rootNode.getToken() == Token.BANG && rootNode.getFirstChild() != null) {
                    rootNode = rootNode.getFirstChild();
                }
                getContext().reportErrorAtOffset(rootNode.getSourceOffset(),
                        String.format("No __proto__ assigned for type %s having @extends",
                                record.typeName));
            }
        }
    }

    private void handleColonNode(Node node) {
        ContextTrackingState state = getState();
        TypeRecord type = state.getCurrentTypeRecord();
        if (type == null) {
            return;
        }
        String propertyName = node.getString();
        if (!PROTO_PROPERTY_NAME.equals(propertyName)) {
            return;
        }
        TypeRecord currentType = state.getCurrentTypeRecord();
        if (currentType == null) {
            // FIXME: __proto__: Foo.prototype not in an object literal for Bar.prototype.
            return;
        }
        typesWithAssignedProto.add(currentType);
        Node rightNode = node.getFirstChild();
        String value = state.getNodeText(rightNode);
        boolean isNullPrototype = "null".equals(value);
        if (!isNullPrototype && !AstUtil.isPrototypeName(value)) {
            reportErrorAtNodeStart(rightNode, "__proto__ value is not a prototype");
            return;
        }
        String superType = isNullPrototype ? "null" : AstUtil.getTypeNameFromPrototype(value);
        if (type.isInterface()) {
            reportErrorAtNodeStart(
                    node, String.format("__proto__ defined for interface %s", type.typeName));
            return;
        } else {
            if (!isNullPrototype && type.getExtendedType() == null) {
                reportErrorAtNodeStart(
                        rightNode, String.format("No @extends annotation for %s extending %s",
                                           type.typeName, superType));
                return;
            }
        }

        if (isNullPrototype) {
            return;
        }

        // FIXME: Should we check that there is only one @extend-ed type
        // for the non-interface |type|? Closure is supposed to do this anyway...
        JSTypeExpression extendedType = type.getExtendedType();
        String extendedTypeName = AstUtil.getAnnotationTypeString(extendedType);
        if (!superType.equals(extendedTypeName)) {
            reportErrorAtNodeStart(rightNode,
                    String.format(
                            "Supertype does not match %s declared in @extends for %s (line %d)",
                            extendedTypeName, type.typeName,
                            state.getContext()
                                    .getPosition(extendedType.getRoot().getSourceOffset())
                                    .line));
        }
    }

    private void handleAssignment(Node assignment) {
        String assignedTypeName =
                getState().getNodeText(AstUtil.getAssignedTypeNameNode(assignment));
        if (assignedTypeName == null) {
            return;
        }
        if (!AstUtil.isPrototypeName(assignedTypeName)) {
            return;
        }
        Node prototypeValueNode = assignment.getLastChild();

        if (prototypeValueNode.getToken() == Token.OBJECTLIT) {
            return;
        }

        // Foo.prototype = notObjectLiteral
        ContextTrackingState state = getState();
        TypeRecord type = state.getCurrentTypeRecord();
        if (type == null) {
            // Assigning a prototype for unknown type. Leave it to the closure compiler.
            return;
        }
        if (type.getExtendedType() != null) {
            reportErrorAtNodeStart(prototypeValueNode,
                    String.format("@extends found for type %s but its prototype is not an object "
                                    + "containing __proto__",
                            AstUtil.getTypeNameFromPrototype(assignedTypeName)));
        }
    }
}
