/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jetbrains.plugins.groovy.codeInspection.assignment;

import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.GroovyBundle;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrParametersOwner;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;

/**
 * @author Maxim.Medvedev
 */
public class GroovyUncheckedAssignmentOfMemberOfRawTypeInspection extends BaseInspection {
  @Override
  @Nls
  @NotNull
  public String getGroupDisplayName() {
    return ASSIGNMENT_ISSUES;
  }

  @Override
  protected String buildErrorString(Object... args) {
    PsiType expectedType = (PsiType)args[0];
    PsiType rType = (PsiType)args[1];
    return GroovyBundle.message("cannot.assign", rType.getPresentableText(), expectedType.getPresentableText());
  }

  @Override
  public boolean isEnabledByDefault() {
    return true;
  }

  @Override
  @NotNull
  protected BaseInspectionVisitor buildVisitor() {
    return new Visitor();
  }

  @Override
  @Nls
  @NotNull
  public String getDisplayName() {
    return "Unchecked assignment from members of raw type";
  }

  private static class Visitor extends BaseInspectionVisitor {
    @Override
    public void visitReturnStatement(GrReturnStatement returnStatement) {
      final GrExpression value = returnStatement.getReturnValue();
      if (value != null) {
        final PsiType type = value.getType();
        if (type != null) {
          final GrParametersOwner owner = PsiTreeUtil.getParentOfType(returnStatement, GrMethod.class, GrClosableBlock.class);
          if (owner instanceof PsiMethod) {
            final PsiMethod method = (PsiMethod)owner;
            if (!method.isConstructor()) {
              final PsiType methodType = method.getReturnType();
              final PsiType returnType = value.getType();
              if (methodType != null) {
                if (!PsiType.VOID.equals(methodType)) {
                  if (returnType != null) {
                    checkAssignability(methodType, value, value);
                  }
                }
              }
            }
          }
        }
      }
    }

    @Override
    public void visitNamedArgument(GrNamedArgument argument) {
      final GrArgumentLabel label = argument.getLabel();
      if (label != null) {
        PsiType expectedType = label.getExpectedArgumentType();
        if (expectedType != null) {
          expectedType = TypeConversionUtil.erasure(expectedType);
          final GrExpression expr = argument.getExpression();
          if (expr != null) {
            final PsiType argType = expr.getType();
            if (argType != null) {
              final PsiClassType listType = JavaPsiFacade.getInstance(argument.getProject()).getElementFactory()
                .createTypeByFQClassName(CommonClassNames.JAVA_UTIL_LIST, argument.getResolveScope());
              if (listType.isAssignableFrom(argType)) return; //this is constructor arguments list
              checkAssignability(expectedType, expr, argument);
            }
          }
        }
      }

    }

    @Override
    public void visitVariable(GrVariable variable) {
      PsiType varType = variable.getType();
      GrExpression initializer = variable.getInitializerGroovy();
      if (initializer != null) {
        PsiType rType = initializer.getType();
        if (rType != null) {
          checkAssignability(varType, initializer, initializer);
        }
      }

    }

    @Override
    public void visitAssignmentExpression(@NotNull GrAssignmentExpression assignment) {
      super.visitAssignmentExpression(assignment);

      GrExpression lValue = assignment.getLValue();
      if (!PsiUtil.mightBeLValue(lValue)) return;

      IElementType opToken = assignment.getOperationTokenType();
      if (opToken != GroovyTokenTypes.mASSIGN) return;

      GrExpression rValue = assignment.getRValue();
      if (rValue == null) return;

      PsiType lType = lValue.getNominalType();
      PsiType rType = rValue.getType();

      // For assignments with spread dot
      if (PsiImplUtil.isSpreadAssignment(lValue) && lType != null && lType instanceof PsiClassType) {
        final PsiClassType pct = (PsiClassType)lType;
        final PsiClass clazz = pct.resolve();
        if (clazz != null && CommonClassNames.JAVA_UTIL_LIST.equals(clazz.getQualifiedName())) {
          final PsiType[] types = pct.getParameters();
          if (types.length == 1 && types[0] != null && rType != null) {
            checkAssignability(types[0], rValue, assignment);
          }
        }
        return;
      }
      if (lValue instanceof GrReferenceExpression &&
          ((GrReferenceExpression)lValue).resolve() instanceof GrReferenceExpression) { //lvalue is nondeclared variable
        return;
      }
      if (lType != null && rType != null) {
        checkAssignability(lType, rValue, rValue);
      }
    }

    private void checkAssignability(PsiType lType, GrExpression rExpr, GroovyPsiElement element) {
      if (PsiUtil.isRawClassMemberAccess(rExpr)) {
        final PsiType rType = rExpr.getType();
        if (!TypesUtil.isAssignable(lType, rType, element)) {
          registerError(element, lType, rType);
        }
      }
    }

  }
}
