/*
 * Copyright 2000-2013 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 com.siyeh.ig.naming;

import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInspection.CommonProblemDescriptor;
import com.intellij.codeInspection.GlobalInspectionContext;
import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.codeInspection.reference.RefPackage;
import com.intellij.codeInspection.ui.ConventionOptionsPanel;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.PsiPackageStatement;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseGlobalInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.BaseSharedLocalInspection;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PackageNamingConventionInspection extends BaseGlobalInspection {

  private static final int DEFAULT_MIN_LENGTH = 3;
  private static final int DEFAULT_MAX_LENGTH = 16;
  /**
   * @noinspection PublicField
   */
  @NonNls
  public String m_regex = "[a-z]*";

  /**
   * @noinspection PublicField
   */
  public int m_minLength = DEFAULT_MIN_LENGTH;

  /**
   * @noinspection PublicField
   */
  public int m_maxLength = DEFAULT_MAX_LENGTH;

  protected Pattern m_regexPattern = Pattern.compile(m_regex);

  @NotNull
  @Override
  public String getDisplayName() {
    return InspectionGadgetsBundle.message("package.naming.convention.display.name");
  }

  @Override
  @Nullable
  public CommonProblemDescriptor[] checkElement(@NotNull RefEntity refEntity, @NotNull AnalysisScope analysisScope,
                                                @NotNull InspectionManager inspectionManager,
                                                @NotNull GlobalInspectionContext globalInspectionContext) {
    if (!(refEntity instanceof RefPackage)) {
      return null;
    }
    @NonNls final String name = refEntity.getName();
    if ("default package".equals(name)) {
      return null;
    }

    final int length = name.length();
    if (length < m_minLength) {
      final String errorString = InspectionGadgetsBundle.message("package.naming.convention.problem.descriptor.short", name);
      return new CommonProblemDescriptor[]{inspectionManager.createProblemDescriptor(errorString)};
    }
    if (length > m_maxLength) {
      final String errorString = InspectionGadgetsBundle.message("package.naming.convention.problem.descriptor.long", name);
      return new CommonProblemDescriptor[]{inspectionManager.createProblemDescriptor(errorString)};
    }
    final Matcher matcher = m_regexPattern.matcher(name);
    if (matcher.matches()) {
      return null;
    }
    else {
      final String errorString =
        InspectionGadgetsBundle.message("package.naming.convention.problem.descriptor.regex.mismatch", name, m_regex);
      return new CommonProblemDescriptor[]{inspectionManager.createProblemDescriptor(errorString)};
    }
  }

  @Override
  public void readSettings(@NotNull Element element) throws InvalidDataException {
    super.readSettings(element);
    m_regexPattern = Pattern.compile(m_regex);
  }

  @Override
  public JComponent createOptionsPanel() {
    return new ConventionOptionsPanel(this, "m_minLength", "m_maxLength", "m_regex", "m_regexPattern");
  }

  boolean isValid(String name) {
    final int length = name.length();
    if (length < m_minLength) {
      return false;
    }
    if (m_maxLength > 0 && length > m_maxLength) {
      return false;
    }
    if (HardcodedMethodConstants.SERIAL_VERSION_UID.equals(name)) {
      return true;
    }
    final Matcher matcher = m_regexPattern.matcher(name);
    return matcher.matches();
  }

  @Nullable
  public LocalInspectionTool getSharedLocalInspectionTool() {
    return new LocalPackageNamingConventionInspection(this);
  }

  private static class LocalPackageNamingConventionInspection extends BaseSharedLocalInspection<PackageNamingConventionInspection> {

    public LocalPackageNamingConventionInspection(PackageNamingConventionInspection inspection) {
      super(inspection);
    }

    @NotNull
    @Override
    protected String buildErrorString(Object... infos) {
      final String name = (String)infos[0];
      if (name.length() < mySettingsDelegate.m_minLength) {
        return InspectionGadgetsBundle.message("package.naming.convention.problem.descriptor.short", name);
      }
      else if (name.length() > mySettingsDelegate.m_maxLength) {
        return InspectionGadgetsBundle.message("package.naming.convention.problem.descriptor.long", name);
      }
      else {
        return InspectionGadgetsBundle.message("package.naming.convention.problem.descriptor.regex.mismatch",
                                               name, mySettingsDelegate.m_regex);
      }
    }

    @Override
    public BaseInspectionVisitor buildVisitor() {
      return new BaseInspectionVisitor() {

        @Override
        public void visitPackageStatement(PsiPackageStatement statement) {
          final PsiJavaCodeReferenceElement reference = statement.getPackageReference();
          if (reference == null) {
            return;
          }
          final String text = reference.getText();
          int start = 0;
          int index = text.indexOf('.', start);
          while (index > 0) {
            final String name = text.substring(start, index);
            if (!mySettingsDelegate.isValid(name)) {
              registerErrorAtOffset(reference, start, index - start, name);
            }
            start = index + 1;
            index = text.indexOf('.', start);
          }
          final String lastName = text.substring(start);
          if (!mySettingsDelegate.isValid(lastName)) {
            registerErrorAtOffset(reference, start, lastName.length(), lastName);
          }
        }
      };
    }
  }
}
