<commit_before>/*
 * Copyright 2000-2005 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.intellij.openapi.application;

import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SystemProperties;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.io.*;

/**
 * @author max
 */
public class ConfigImportHelper {
  @NonNls private static final String BUILD_NUMBER_FILE = "build.txt";
  @NonNls private static final String PLUGINS_PATH = "plugins";
  @NonNls private static final String BIN_FOLDER = "bin";

  private ConfigImportHelper() {}

  public static void importConfigsTo(String newConfigPath) {
    do {
      ImportOldConfigsPanel dlg = new ImportOldConfigsPanel();
      dlg.setVisible(true);
      if (dlg.isImportEnabled()) {
        File instHome = dlg.getSelectedFile();
        File oldConfigDir = getOldConfigDir(instHome);
        if (oldConfigDir == null) {
          JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                                        ApplicationBundle.message("error.invalid.installation.home", instHome.getAbsolutePath(),
                                                                  ApplicationNamesInfo.getInstance().getFullProductName()));
          continue;
        }

        if (!oldConfigDir.exists()) {
          JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                                        ApplicationBundle.message("error.no.settings.path",
                                                                  oldConfigDir.getAbsolutePath()),
                                        ApplicationBundle.message("title.settings.import.failed"), JOptionPane.WARNING_MESSAGE);
          continue;
        }

        try {
          xcopy(oldConfigDir, new File(newConfigPath));
        }
        catch (IOException e) {
          JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                                        ApplicationBundle.message("error.unable.to.import.settings", e.getMessage()),
                                        ApplicationBundle.message("title.settings.import.failed"), JOptionPane.WARNING_MESSAGE);
        }
      }

      break;
    }
    while (true);
  }

  public static void xcopy(File src, File dest) throws IOException{
    src = src.getCanonicalFile();
    dest = dest.getCanonicalFile();
    if (!src.isDirectory()){
      throw new IOException(ApplicationBundle.message("config.import.invalid.directory.error", src.getAbsolutePath()));
    }
    if (!dest.isDirectory()){
      throw new IOException(ApplicationBundle.message("config.import.invalid.directory.error", dest.getAbsolutePath()));
    }
    FileUtil.copyDir(src, dest);

    // Delete plugins just imported. They're most probably incompatible with newer idea version.
    File plugins = new File(dest, PLUGINS_PATH);
    if (plugins.exists()) {
      FileUtil.delete(plugins);
    }
  }

  @Nullable
  public static File getOldConfigDir(File oldInstallHome) {
    int oldBuildNumber = getBuildNumber(oldInstallHome);

    if (oldBuildNumber != -1 && oldBuildNumber <= 600) { // Pandora
      //noinspection HardCodedStringLiteral
      return new File(oldInstallHome, "config");
    }

    File[] launchFileCandidates = getLaunchFilesCandidates(oldInstallHome);
    for (File file : launchFileCandidates) {
      if (file.exists()) {
        String parseString = getContent(file);
        String configDir = PathManager.substituteVars(getConfigFromLaxFile(parseString), oldInstallHome.getPath());
        if (configDir != null) {
          File probableConfig = new File(configDir);
          if (probableConfig.exists()) return probableConfig;
        }
      }
    }

    return null;
  }

  @SuppressWarnings({"HardCodedStringLiteral"})
  private static File[] getLaunchFilesCandidates(File instHome) {
    File bin = new File(instHome, BIN_FOLDER);
    return new File[]{
      new File(bin, "idea.properties"),
      new File(bin, "idea.lax"),
      new File(bin, "idea.bat"),
      new File(bin, "idea.sh"),
      new File(new File(instHome, "Contents"), "Info.plist"),
      new File(new File(new File(bin, "idea.app"), "Contents"), "Info.plist"),
      new File(new File(new File(instHome, "idea.app"), "Contents"), "Info.plist")
    };
  }

  @SuppressWarnings({"HardCodedStringLiteral"})
  @Nullable
  public static String getConfigFromLaxFile(String fileContent) {
    String configParam = "idea.config.path=";
    int idx = fileContent.indexOf(configParam);
    if (idx == -1) {
      configParam = "<key>idea.config.path</key>";
      idx = fileContent.indexOf(configParam);
      if (idx == -1) return null;
      idx = fileContent.indexOf("<string>", idx);
      if (idx == -1) return null;
      idx += "<string>".length();
      return fixDirName(fileContent.substring(idx, fileContent.indexOf("</string>", idx)), true);
    }
    else {
      String configDir = "";
      idx += configParam.length();
      if (fileContent.length() > idx) {
        if (fileContent.charAt(idx) == '"') {
          idx++;
          while ((fileContent.length() > idx) && (fileContent.charAt(idx) != '"') && (fileContent.charAt(idx) != '\n') &&
                 (fileContent.charAt(idx) != '\r')) {
            configDir += fileContent.charAt(idx);
            idx++;
          }
        }
        else {
          while ((fileContent.length() > idx) && (!Character.isSpaceChar(fileContent.charAt(idx))) &&
                 (fileContent.charAt(idx) != '\n') &&
                 (fileContent.charAt(idx) != '\r')) {
            configDir += fileContent.charAt(idx);
            idx++;
          }
        }
      }
      configDir = fixDirName(configDir, true);
      if (configDir.length() > 0) {
        configDir = (new File(configDir)).getPath();
      }
      return configDir;
    }
  }

  @Nullable
  private static String getContent(File file) {
    try {
      BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
      StringBuffer content = new StringBuffer();
      do {
        String line = reader.readLine();
        if (line == null) break;
        content.append(line);
        content.append('\n');
      }
      while (true);

      return content.toString();
    }
    catch (Exception e) {<commit_msg>More correct settings import in case of .properties file.<commit_after>/*
 * Copyright 2000-2005 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.intellij.openapi.application;

import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SystemProperties;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.io.*;
import java.util.PropertyResourceBundle;

/**
 * @author max
 */
public class ConfigImportHelper {
  @NonNls private static final String BUILD_NUMBER_FILE = "build.txt";
  @NonNls private static final String PLUGINS_PATH = "plugins";
  @NonNls private static final String BIN_FOLDER = "bin";

  private ConfigImportHelper() {}

  public static void importConfigsTo(String newConfigPath) {
    do {
      ImportOldConfigsPanel dlg = new ImportOldConfigsPanel();
      dlg.setVisible(true);
      if (dlg.isImportEnabled()) {
        File instHome = dlg.getSelectedFile();
        File oldConfigDir = getOldConfigDir(instHome);
        if (oldConfigDir == null) {
          JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                                        ApplicationBundle.message("error.invalid.installation.home", instHome.getAbsolutePath(),
                                                                  ApplicationNamesInfo.getInstance().getFullProductName()));
          continue;
        }

        if (!oldConfigDir.exists()) {
          JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                                        ApplicationBundle.message("error.no.settings.path",
                                                                  oldConfigDir.getAbsolutePath()),
                                        ApplicationBundle.message("title.settings.import.failed"), JOptionPane.WARNING_MESSAGE);
          continue;
        }

        try {
          xcopy(oldConfigDir, new File(newConfigPath));
        }
        catch (IOException e) {
          JOptionPane.showMessageDialog(JOptionPane.getRootFrame(),
                                        ApplicationBundle.message("error.unable.to.import.settings", e.getMessage()),
                                        ApplicationBundle.message("title.settings.import.failed"), JOptionPane.WARNING_MESSAGE);
        }
      }

      break;
    }
    while (true);
  }

  public static void xcopy(File src, File dest) throws IOException{
    src = src.getCanonicalFile();
    dest = dest.getCanonicalFile();
    if (!src.isDirectory()){
      throw new IOException(ApplicationBundle.message("config.import.invalid.directory.error", src.getAbsolutePath()));
    }
    if (!dest.isDirectory()){
      throw new IOException(ApplicationBundle.message("config.import.invalid.directory.error", dest.getAbsolutePath()));
    }
    FileUtil.copyDir(src, dest);

    // Delete plugins just imported. They're most probably incompatible with newer idea version.
    File plugins = new File(dest, PLUGINS_PATH);
    if (plugins.exists()) {
      FileUtil.delete(plugins);
    }
  }

  @Nullable
  public static File getOldConfigDir(File oldInstallHome) {
    int oldBuildNumber = getBuildNumber(oldInstallHome);

    if (oldBuildNumber != -1 && oldBuildNumber <= 600) { // Pandora
      //noinspection HardCodedStringLiteral
      return new File(oldInstallHome, "config");
    }

    File[] launchFileCandidates = getLaunchFilesCandidates(oldInstallHome);
    for (File file : launchFileCandidates) {
      if (file.exists()) {
        String configDir = PathManager.substituteVars(getConfigFromLaxFile(file), oldInstallHome.getPath());
        if (configDir != null) {
          File probableConfig = new File(configDir);
          if (probableConfig.exists()) return probableConfig;
        }
      }
    }

    return null;
  }

  @SuppressWarnings({"HardCodedStringLiteral"})
  private static File[] getLaunchFilesCandidates(File instHome) {
    File bin = new File(instHome, BIN_FOLDER);
    return new File[]{
      new File(bin, "idea.properties"),
      new File(bin, "idea.lax"),
      new File(bin, "idea.bat"),
      new File(bin, "idea.sh"),
      new File(new File(instHome, "Contents"), "Info.plist"),
      new File(new File(new File(bin, "idea.app"), "Contents"), "Info.plist"),
      new File(new File(new File(instHome, "idea.app"), "Contents"), "Info.plist")
    };
  }

  @SuppressWarnings({"HardCodedStringLiteral"})
  @Nullable
  public static String getConfigFromLaxFile(File file) {
      if (file.getName().endsWith(".properties")) {
          try {
              InputStream fis = new BufferedInputStream(new FileInputStream(file));
              PropertyResourceBundle bundle = new PropertyResourceBundle(fis);
              fis.close();
              return bundle.getString("idea.config.path");
          } catch (IOException e) {
              return null;
          }
      }

      String fileContent = getContent(file);
      String configParam = "idea.config.path=";
      int idx = fileContent.indexOf(configParam);
      if (idx == -1) {
          configParam = "<key>idea.config.path</key>";
          idx = fileContent.indexOf(configParam);
          if (idx == -1) return null;
          idx = fileContent.indexOf("<string>", idx);
          if (idx == -1) return null;
          idx += "<string>".length();
          return fixDirName(fileContent.substring(idx, fileContent.indexOf("</string>", idx)), true);
      } else {
          String configDir = "";
          idx += configParam.length();
          if (fileContent.length() > idx) {
              if (fileContent.charAt(idx) == '"') {
                  idx++;
                  while ((fileContent.length() > idx) && (fileContent.charAt(idx) != '"') && (fileContent.charAt(idx) != '\n') &&
                          (fileContent.charAt(idx) != '\r')) {
                      configDir += fileContent.charAt(idx);
                      idx++;
                  }
              } else {
                  while ((fileContent.length() > idx) && (!Character.isSpaceChar(fileContent.charAt(idx))) &&
                          (fileContent.charAt(idx) != '\n') &&
                          (fileContent.charAt(idx) != '\r')) {
                      configDir += fileContent.charAt(idx);
                      idx++;
                  }
              }
          }
          configDir = fixDirName(configDir, true);
          if (configDir.length() > 0) {
              configDir = (new File(configDir)).getPath();
          }
          return configDir;
      }
  }

  @Nullable
  private static String getContent(File file) {
    try {
      BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
      StringBuffer content = new StringBuffer();
      do {
        String line = reader.readLine();
        if (line == null) break;
        content.append(line);
        content.append('\n');
      }
      while (true);

      return content.toString();
    }
    catch (Exception e) {
{'fraction_non_alphanumeric': 0.12016012147146111, 'fraction_numerical': 0.0027607150251915246, 'mean_word_length': 2.441805225653207, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5216564', 'n_tokens_mistral': 3910, 'n_tokens_neox': 3833, 'n_words': 906}