/*
 * 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.
 */

/**
 * @author cdr
 */
package com.intellij.lang.properties.references;

import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.util.TreeFileChooser;
import com.intellij.ide.util.TreeFileChooserFactory;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.LastSelectedPropertiesFileStore;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.help.HelpManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.GuiUtils;
import com.intellij.ui.TextFieldWithHistory;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.text.Normalizer;
import java.util.*;
import java.util.List;
import java.util.regex.Pattern;

public class I18nizeQuickFixDialog extends DialogWrapper implements I18nizeQuickFixModel {
  protected static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.i18n.I18nizeQuickFixDialog");
  
  private static final Pattern PATTERN = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");

  private JTextField myValue;
  private JComboBox myKey;
  private final TextFieldWithHistory myPropertiesFile;
  protected JPanel myPanel;
  private JCheckBox myUseResourceBundle;
  protected final Project myProject;
  protected final PsiFile myContext;

  private JPanel myPropertiesFilePanel;
  protected JPanel myExtensibilityPanel;

  protected final String myDefaultPropertyValue;
  protected final DialogCustomization myCustomization;

  public static class DialogCustomization {
    private final String title;
    private final boolean suggestExistingProperties;
    private final boolean focusValueComponent;
    private final List<PropertiesFile> propertiesFiles;
    private final String suggestedName;

    public DialogCustomization(String title, boolean suggestExistingProperties, boolean focusValueComponent,
                               List<PropertiesFile> propertiesFiles,
                               String suggestedName) {
      this.title = title;
      this.suggestExistingProperties = suggestExistingProperties;
      this.focusValueComponent = focusValueComponent;
      this.propertiesFiles = propertiesFiles;
      this.suggestedName = suggestedName;
    }

    public DialogCustomization() {
      this(null, true, false, null, null);
    }

    public String getSuggestedName() {
      return suggestedName;
    }
  }

  public I18nizeQuickFixDialog(@NotNull Project project,
                               @NotNull final PsiFile context,
                               String defaultPropertyValue,
                               DialogCustomization customization
                               ) {
    this(project, context, defaultPropertyValue, customization, false);
  }

  protected I18nizeQuickFixDialog(@NotNull Project project,
                               @NotNull final PsiFile context,
                               String defaultPropertyValue,
                               DialogCustomization customization,
                               boolean ancestorResponsible) {
    super(false);
    myProject = project;
    myContext = context;

    myDefaultPropertyValue = defaultPropertyValue;
    myCustomization = customization != null ? customization:new DialogCustomization();
    setTitle(myCustomization.title != null ? myCustomization.title:CodeInsightBundle.message("i18nize.dialog.title"));

    myPropertiesFile = new TextFieldWithHistory();
    myPropertiesFile.setHistorySize(-1);
    myPropertiesFilePanel.add(GuiUtils.constructFieldWithBrowseButton(myPropertiesFile, new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        TreeFileChooserFactory chooserFactory = TreeFileChooserFactory.getInstance(myProject);
        final PropertiesFile propertiesFile = getPropertiesFile();
        TreeFileChooser fileChooser = chooserFactory.createFileChooser(
          CodeInsightBundle.message("i18nize.dialog.property.file.chooser.title"), propertiesFile != null ? propertiesFile.getContainingFile() : null, StdFileTypes.PROPERTIES, null);
        fileChooser.showDialog();
        PsiFile selectedFile = fileChooser.getSelectedFile();
        if (selectedFile == null) return;
        myPropertiesFile.setText(FileUtil.toSystemDependentName(selectedFile.getVirtualFile().getPath()));
      }
    }), BorderLayout.CENTER);

    myPropertiesFile.addDocumentListener(new DocumentAdapter() {
      @Override
      protected void textChanged(DocumentEvent e) {
        propertiesFileChanged();
        somethingChanged();
      }
    });

    getKeyTextField().getDocument().addDocumentListener(new DocumentAdapter() {
      @Override
      protected void textChanged(DocumentEvent e) {
        somethingChanged();
      }
    });

    myValue.getDocument().addDocumentListener(new DocumentAdapter() {
      @Override
      protected void textChanged(DocumentEvent e) {
        somethingChanged();
      }
    });


    @NonNls final String KEY = "I18NIZE_DIALOG_USE_RESOURCE_BUNDLE";
    final boolean useBundleByDefault =
      !PropertiesComponent.getInstance().isValueSet(KEY) || PropertiesComponent.getInstance().isTrueValue(KEY);
    myUseResourceBundle.setSelected(useBundleByDefault);
    myUseResourceBundle.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        PropertiesComponent.getInstance().setValue(KEY, Boolean.valueOf(myUseResourceBundle.isSelected()).toString());
      }
    });

    if (!ancestorResponsible) init();
  }

  @Override
  protected void init() {
    populatePropertiesFiles();
    propertiesFileChanged();
    somethingChanged();
    setKeyValueEditBoxes();

    super.init();
  }

  private JTextField getKeyTextField() {
    return (JTextField)myKey.getEditor().getEditorComponent();
  }

  @NotNull
  protected List<String> getExistingValueKeys(String value) {
    if(!myCustomization.suggestExistingProperties) {
      return Collections.emptyList();
    }
    final ArrayList<String> result = new ArrayList<String>();

    // check if property value already exists among properties file values and suggest corresponding key
    PropertiesFile propertiesFile = getPropertiesFile();
    if (propertiesFile != null) {
      for (IProperty property : propertiesFile.getProperties()) {
        if (Comparing.strEqual(property.getValue(), value)) {
          result.add(0, property.getUnescapedKey());
        }
      }
    }
    return result;
  }

  protected String suggestPropertyKey(String value) {
    if (myCustomization.suggestedName != null) {
      return myCustomization.suggestedName;
    }

    // suggest property key not existing in this file
    String key = defaultSuggestPropertyKey(value);
    value = PATTERN.matcher(Normalizer.normalize(value, Normalizer.Form.NFD)).replaceAll("");
    if (key == null) {
      final StringBuilder result = new StringBuilder();
      boolean insertDotBeforeNextWord = false;
      for (int i = 0; i < value.length(); i++) {
        final char c = value.charAt(i);
        if (Character.isLetterOrDigit(c)) {
          if (insertDotBeforeNextWord) {
            result.append('.');
          }
          result.append(Character.toLowerCase(c));
          insertDotBeforeNextWord = false;
        }
        else if (c == '&') {   //do not insert dot if there is letter after the amp
          if (insertDotBeforeNextWord) continue;
          if (i == value.length() - 1) {
            continue;
          }
          if (Character.isLetter(value.charAt(i + 1))) {
            continue;
          }
          insertDotBeforeNextWord = true;
        }
        else {
          if (result.length() > 0) {
            insertDotBeforeNextWord = true;
          }
        }
      }
      key = result.toString();
    }

    PropertiesFile propertiesFile = getPropertiesFile();
    if (propertiesFile != null) {
      if (propertiesFile.findPropertyByKey(key) == null) return key;

      int suffix = 1;
      while (propertiesFile.findPropertyByKey(key + suffix) != null) {
        suffix++;
      }
      return key + suffix;
    }
    else {
      return key;
    }
  }

  protected String defaultSuggestPropertyKey(String value) {
    return null;  
  }

  private void propertiesFileChanged() {
    PropertiesFile propertiesFile = getPropertiesFile();
    boolean hasResourceBundle =
      propertiesFile != null && propertiesFile.getResourceBundle().getPropertiesFiles().size() > 1;
    myUseResourceBundle.setEnabled(hasResourceBundle);
  }

  private void setKeyValueEditBoxes() {
    final List<String> existingValueKeys = getExistingValueKeys(myDefaultPropertyValue);

    if (existingValueKeys.isEmpty()) {
      getKeyTextField().setText(suggestPropertyKey(myDefaultPropertyValue));
    }
    else {
      for (String key : existingValueKeys) {
        myKey.addItem(key);
      }
      myKey.setSelectedItem(existingValueKeys.get(0));
    }


    myValue.setText(myDefaultPropertyValue);
  }

  protected void somethingChanged() {
    setOKActionEnabled(!StringUtil.isEmptyOrSpaces(getKey()));
  }

  private void populatePropertiesFiles() {
    List<String> paths = suggestPropertiesFiles();
    final String lastUrl = suggestSelectedFileUrl(paths);
    final String lastPath = lastUrl == null ? null : FileUtil.toSystemDependentName(VfsUtil.urlToPath(lastUrl));
    Collections.sort(paths, new Comparator<String>() {
      @Override
      public int compare(final String path1, final String path2) {
        if (lastPath != null && lastPath.equals(path1)) return -1;
        if (lastPath != null && lastPath.equals(path2)) return 1;
        int r = LastSelectedPropertiesFileStore.getUseCount(path2) - LastSelectedPropertiesFileStore.getUseCount(path1);
        return r == 0 ? path1.compareTo(path2) : r;
      }
    });
    myPropertiesFile.setHistory(paths);
    if (lastPath != null) {
      myPropertiesFile.setSelectedItem(lastPath);
    }
    if (myPropertiesFile.getSelectedIndex() == -1 && !paths.isEmpty()) {
      myPropertiesFile.setText(paths.get(0));
    }
  }

  private String suggestSelectedFileUrl(List<String> paths) {
    if (myDefaultPropertyValue != null) {
      for (String path : paths) {
        VirtualFile file = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(path));
        if (file == null) continue;
        PsiFile psiFile = myContext.getManager().findFile(file);
        if (!(psiFile instanceof PropertiesFile)) continue;
        for (IProperty property : ((PropertiesFile)psiFile).getProperties()) {
          if (property.getValue().equals(myDefaultPropertyValue)) return path;
        }
      }
    }
    return LastSelectedPropertiesFileStore.getInstance().suggestLastSelectedPropertiesFileUrl(myContext);
  }

  private void saveLastSelectedFile() {
    PropertiesFile propertiesFile = getPropertiesFile();
    if (propertiesFile != null) {
      LastSelectedPropertiesFileStore.getInstance().saveLastSelectedPropertiesFile(myContext, propertiesFile);
    }
  }

  protected List<String> suggestPropertiesFiles() {
    if (myCustomization.propertiesFiles != null && !myCustomization.propertiesFiles.isEmpty()) {
      ArrayList<String> list = new ArrayList<String>();
      for (PropertiesFile propertiesFile : myCustomization.propertiesFiles) {
        final VirtualFile virtualFile = propertiesFile.getVirtualFile();
        if (virtualFile != null) {
          list.add(virtualFile.getPath());
        }
      }
      return list;
    }
    return defaultSuggestPropertiesFiles();
  }

  protected List<String> defaultSuggestPropertiesFiles() {
    return I18nUtil.defaultGetPropertyFiles(myProject);
  }

  protected PropertiesFile getPropertiesFile() {
    String path = FileUtil.toSystemIndependentName(myPropertiesFile.getText());
    VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(path);
    if (virtualFile != null) {
      PsiFile psiFile = PsiManager.getInstance(myProject).findFile(virtualFile);
      if (psiFile instanceof PropertiesFile) return (PropertiesFile)psiFile;
    }
    return null;
  }

  private boolean createPropertiesFileIfNotExists() {
    if (getPropertiesFile() != null) return true;
    final String path = FileUtil.toSystemIndependentName(myPropertiesFile.getText());
    if (StringUtil.isEmptyOrSpaces(path)) {
      String message = CodeInsightBundle.message("i18nize.empty.file.path", myPropertiesFile.getText());
      Messages.showErrorDialog(myProject, message, CodeInsightBundle.message("i18nize.error.creating.properties.file"));
      myPropertiesFile.requestFocusInWindow();
      return false;
    }
    FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(path);
    if (fileType != StdFileTypes.PROPERTIES) {
      String message = CodeInsightBundle.message("i18nize.cant.create.properties.file.because.its.name.is.associated",
                                                 myPropertiesFile.getText(), fileType.getDescription());
      Messages.showErrorDialog(myProject, message, CodeInsightBundle.message("i18nize.error.creating.properties.file"));
      myPropertiesFile.requestFocusInWindow();
      return false;
    }

    final VirtualFile virtualFile;
    try {
      final File file = new File(path).getCanonicalFile();
      FileUtil.createParentDirs(file);
      virtualFile = ApplicationManager.getApplication().runWriteAction(new ThrowableComputable<VirtualFile, IOException>() {
        @Override
        public VirtualFile compute() throws IOException {
          VirtualFile dir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file.getParentFile());
          if (dir == null) {
            throw new IOException("Error creating directory structure for file '" + path + "'");
          }
          return dir.createChildData(this, file.getName());
        }
      });
    }
    catch (IOException e) {
      Messages.showErrorDialog(myProject, e.getLocalizedMessage(), CodeInsightBundle.message("i18nize.error.creating.properties.file"));
      return false;
    }

    PsiFile psiFile = PsiManager.getInstance(myProject).findFile(virtualFile);
    return psiFile instanceof PropertiesFile;
  }

  @Override
  protected JComponent createCenterPanel() {
    return myPanel;
  }

  @Override
  public JComponent getPreferredFocusedComponent() {
    return myCustomization.focusValueComponent ? myValue:myKey;
  }

  @Override
  public void dispose() {
    saveLastSelectedFile();
    super.dispose();
  }

  @Override
  protected void doOKAction() {
    if (!createPropertiesFileIfNotExists()) return;
    Collection<PropertiesFile> propertiesFiles = getAllPropertiesFiles();
    for (PropertiesFile propertiesFile : propertiesFiles) {
      IProperty existingProperty = propertiesFile.findPropertyByKey(getKey());
      final String propValue = myValue.getText();
      if (existingProperty != null && !Comparing.strEqual(existingProperty.getValue(), propValue)) {
        Messages.showErrorDialog(myProject, CodeInsightBundle.message("i18nize.dialog.error.property.already.defined.message", getKey(),
                                                                      propertiesFile.getName()),
                                            CodeInsightBundle.message("i18nize.dialog.error.property.already.defined.title"));
        return;
      }
    }

    super.doOKAction();
  }

  @Override
  @NotNull
  protected Action[] createActions() {
    return new Action[]{getOKAction(), getCancelAction(), getHelpAction()};
  }

  @Override
  public void doHelpAction() {
    HelpManager.getInstance().invokeHelp("editing.propertyFile.i18nInspection");
  }


  public JComponent getValueComponent() {
    return myValue;
  }

  @Override
  public String getValue() {
    return myValue.getText();
  }

  @Override
  public String getKey() {
    return getKeyTextField().getText();
  }

  @Override
  public boolean hasValidData() {
    assert !ApplicationManager.getApplication().isUnitTestMode();
    show();

    return getExitCode() == OK_EXIT_CODE;
  }

  private boolean isUseResourceBundle() {
    return myUseResourceBundle.isEnabled() && myUseResourceBundle.isSelected();
  }

  @Override
  protected String getDimensionServiceKey() {
    return "#com.intellij.codeInsight.i18n.I18nizeQuickFixDialog";
  }

  @Override
  public Collection<PropertiesFile> getAllPropertiesFiles() {
    PropertiesFile propertiesFile = getPropertiesFile();
    if (propertiesFile == null) return Collections.emptySet();
    Collection<PropertiesFile> propertiesFiles;
    if (isUseResourceBundle()) {
      propertiesFiles = propertiesFile.getResourceBundle().getPropertiesFiles();
    }
    else {
      propertiesFiles = Collections.singleton(propertiesFile);
    }
    return propertiesFiles;
  }
}
