  /*
 * Copyright 2000-2011 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 git4idea.repo;

  import com.intellij.dvcs.repo.RepoStateException;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import git4idea.GitLocalBranch;
import git4idea.GitPlatformFacade;
import git4idea.GitRemoteBranch;
import git4idea.GitSvnRemoteBranch;
import git4idea.branch.GitBranchUtil;
import org.ini4j.Ini;
import org.ini4j.Profile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>Reads information from the {@code .git/config} file, and parses it to actual objects.</p>
 *
 * <p>Currently doesn't read all the information: general information about remotes and branch tracking</p>
 *
 * <p>Parsing is performed with the help of <a href="http://ini4j.sourceforge.net/">ini4j</a> library.</p>
 *
 * TODO: note, that other git configuration files (such as ~/.gitconfig) are not handled yet.
 * 
 * @author Kirill Likhodedov
 */
public class GitConfig {

  /**
   * Special remote typical for git-svn configuration:
   * <pre>[branch "trunk]
   *   remote = .
   *   merge = refs/remotes/trunk
   * </pre>
   * @deprecated Use {@link GitSvnRemoteBranch}
   */
  @Deprecated
  public static final String DOT_REMOTE = ".";

  private static final Logger LOG = Logger.getInstance(GitConfig.class);

  private static final Pattern REMOTE_SECTION = Pattern.compile("(?:svn-)?remote \"(.*)\"");
  private static final Pattern URL_SECTION = Pattern.compile("url \"(.*)\"");
  private static final Pattern BRANCH_INFO_SECTION = Pattern.compile("branch \"(.*)\"");
  private static final Pattern BRANCH_COMMON_PARAMS_SECTION = Pattern.compile("branch");

  @NotNull private final Collection<Remote> myRemotes;
  @NotNull private final Collection<Url> myUrls;
  @NotNull private final Collection<BranchConfig> myTrackedInfos;


  private GitConfig(@NotNull Collection<Remote> remotes, @NotNull Collection<Url> urls, @NotNull Collection<BranchConfig> trackedInfos) {
    myRemotes = remotes;
    myUrls = urls;
    myTrackedInfos = trackedInfos;
  }

  /**
   * <p>Returns Git remotes defined in {@code .git/config}.</p>
   *
   * <p>Remote is returned with all transformations (such as {@code pushUrl, url.<base>.insteadOf}) already applied to it.
   *    See {@link GitRemote} for details.</p>
   *
   * <p><b>Note:</b> remotes can be defined separately in {@code .git/remotes} directory, by creating a file for each remote with
   *    remote parameters written in the file. This method returns ONLY remotes defined in {@code .git/config}.</p>
   * @return Git remotes defined in {@code .git/config}.
   */
  @NotNull
  Collection<GitRemote> parseRemotes() {
    // populate GitRemotes with substituting urls when needed
    return ContainerUtil.map(myRemotes, new Function<Remote, GitRemote>() {
      @Override
      public GitRemote fun(@Nullable Remote remote) {
        assert remote != null;
        return convertRemoteToGitRemote(myUrls, remote);
      }
    });
  }

  @NotNull
  private static GitRemote convertRemoteToGitRemote(@NotNull Collection<Url> urls, @NotNull Remote remote) {
    UrlsAndPushUrls substitutedUrls = substituteUrls(urls, remote);
    return new GitRemote(remote.myName, substitutedUrls.getUrls(), substitutedUrls.getPushUrls(),
                         remote.getFetchSpecs(), computePushSpec(remote));
  }

  /**
   * Create branch tracking information based on the information defined in {@code .git/config}.
   */
  @NotNull
  Collection<GitBranchTrackInfo> parseTrackInfos(@NotNull final Collection<GitLocalBranch> localBranches,
                                                 @NotNull final Collection<GitRemoteBranch> remoteBranches) {
    return ContainerUtil.mapNotNull(myTrackedInfos, new Function<BranchConfig, GitBranchTrackInfo>() {
      @Override
      public GitBranchTrackInfo fun(BranchConfig config) {
        if (config != null) {
          return convertBranchConfig(config, localBranches, remoteBranches);
        }
        return null;
      }
    });
  }

  /**
   * Creates an instance of GitConfig by reading information from the specified {@code .git/config} file.
   * @throws RepoStateException if {@code .git/config} couldn't be read or has invalid format.<br/>
   *         If in general it has valid format, but some sections are invalid, it skips invalid sections, but reports an error.
   */
  @NotNull
  static GitConfig read(@NotNull GitPlatformFacade platformFacade, @NotNull File configFile) {
    GitConfig emptyConfig = new GitConfig(Collections.<Remote>emptyList(), Collections.<Url>emptyList(),
                                          Collections.<BranchConfig>emptyList());
    if (!configFile.exists()) {
      LOG.info("No .git/config file at " + configFile.getPath());
      return emptyConfig;
    }

    Ini ini = new Ini();
    ini.getConfig().setMultiOption(true);  // duplicate keys (e.g. url in [remote])
    ini.getConfig().setTree(false);        // don't need tree structure: it corrupts url in section name (e.g. [url "http://github.com/"]
    try {
      ini.load(configFile);
    }
    catch (IOException e) {
      LOG.warn(new RepoStateException("Couldn't load .git/config file at " + configFile.getPath(), e));
      return emptyConfig;
    }

    IdeaPluginDescriptor plugin = platformFacade.getPluginByClassName(GitConfig.class.getName());
    ClassLoader classLoader = plugin == null ? null : plugin.getPluginClassLoader(); // null if IDEA is started from IDEA

    Pair<Collection<Remote>, Collection<Url>> remotesAndUrls = parseRemotes(ini, classLoader);
    Collection<BranchConfig> trackedInfos = parseTrackedInfos(ini, classLoader);
    
    return new GitConfig(remotesAndUrls.getFirst(), remotesAndUrls.getSecond(), trackedInfos);
  }

  @NotNull
  private static Collection<BranchConfig> parseTrackedInfos(@NotNull Ini ini, @Nullable ClassLoader classLoader) {
    Collection<BranchConfig> configs = new ArrayList<BranchConfig>();
    for (Map.Entry<String, Profile.Section> stringSectionEntry : ini.entrySet()) {
      String sectionName = stringSectionEntry.getKey();
      Profile.Section section = stringSectionEntry.getValue();
      if (sectionName.startsWith("branch")) {
        BranchConfig branchConfig = parseBranchSection(sectionName, section,  classLoader);
        if (branchConfig != null) {
          configs.add(branchConfig);
        }
      }
    }
    return configs;
  }

  @Nullable
  private static GitBranchTrackInfo convertBranchConfig(@Nullable BranchConfig branchConfig,
                                                        @NotNull Collection<GitLocalBranch> localBranches,
                                                        @NotNull Collection<GitRemoteBranch> remoteBranches) {
    if (branchConfig == null) {
      return null;
    }
    final String branchName = branchConfig.getName();
    String remoteName = branchConfig.getBean().getRemote();
    String mergeName = branchConfig.getBean().getMerge();
    String rebaseName = branchConfig.getBean().getRebase();

    if (StringUtil.isEmptyOrSpaces(mergeName) && StringUtil.isEmptyOrSpaces(rebaseName)) {
      LOG.info("No branch." + branchName + ".merge/rebase item in the .git/config");
      return null;
    }
    if (StringUtil.isEmptyOrSpaces(remoteName)) {
      LOG.info("No branch." + branchName + ".remote item in the .git/config");
      return null;
    }

    boolean merge = mergeName != null;
    final String remoteBranchName = (merge ? mergeName : rebaseName);
    assert remoteName != null;
    assert remoteBranchName != null;

    GitLocalBranch localBranch = findLocalBranch(branchName, localBranches);
    GitRemoteBranch remoteBranch = GitBranchUtil.findRemoteBranchByName(remoteBranchName, remoteName, remoteBranches);
    if (localBranch == null || remoteBranch == null) {
      return null;
    }
    return new GitBranchTrackInfo(localBranch, remoteBranch, merge);
  }

  @Nullable
  private static GitLocalBranch findLocalBranch(@NotNull String branchName, @NotNull Collection<GitLocalBranch> localBranches) {
    final String name = GitBranchUtil.stripRefsPrefix(branchName);
    try {
      return ContainerUtil.find(localBranches, new Condition<GitLocalBranch>() {
        @Override
        public boolean value(@Nullable GitLocalBranch input) {
          assert input != null;
          return input.getName().equals(name);
        }
      });
    }
    catch (NoSuchElementException e) {
      LOG.info("Couldn't find branch with name " + name);
      return null;
    }
  }

  @Nullable
  private static BranchConfig parseBranchSection(String sectionName, Profile.Section section, @Nullable ClassLoader classLoader) {
    BranchBean branchBean = section.as(BranchBean.class, classLoader);
    Matcher matcher = BRANCH_INFO_SECTION.matcher(sectionName);
    if (matcher.matches()) {
      return new BranchConfig(matcher.group(1), branchBean);
    }
    if (BRANCH_COMMON_PARAMS_SECTION.matcher(sectionName).matches()) {
      LOG.debug(String.format("Common branch option(s) defined .git/config. sectionName: %s%n section: %s", sectionName, section));
      return null;
    }
    LOG.error(String.format("Invalid branch section format in .git/config. sectionName: %s%n section: %s", sectionName, section));
    return null;
  }

  @NotNull
  private static Pair<Collection<Remote>, Collection<Url>> parseRemotes(@NotNull Ini ini, @Nullable ClassLoader classLoader) {
    Collection<Remote> remotes = new ArrayList<Remote>();
    Collection<Url> urls = new ArrayList<Url>();
    for (Map.Entry<String, Profile.Section> stringSectionEntry : ini.entrySet()) {
      String sectionName = stringSectionEntry.getKey();
      Profile.Section section = stringSectionEntry.getValue();

      if (sectionName.startsWith("remote") || sectionName.startsWith("svn-remote")) {
        Remote remote = parseRemoteSection(sectionName, section, classLoader);
        if (remote != null) {
          remotes.add(remote);
        }
      }
      else if (sectionName.startsWith("url")) {
        Url url = parseUrlSection(sectionName, section, classLoader);
        if (url != null) {
          urls.add(url);
        }
      }
    }
    return Pair.create(remotes, urls);
  }

  @NotNull
  private static List<String> computePushSpec(@NotNull Remote remote) {
    List<String> pushSpec = remote.getPushSpec();
    return pushSpec == null ? remote.getFetchSpecs() : pushSpec;
  }

  /**
   * <p>
   *   Applies {@code url.<base>.insteadOf} and {@code url.<base>.pushInsteadOf} transformations to {@code url} and {@code pushUrl} of
   *   the given remote.
   * </p>
   * <p>
   *   The logic, is as follows:
   *   <ul>
   *     <li>If remote.url starts with url.insteadOf, it it substituted.</li>
   *     <li>If remote.pushUrl starts with url.insteadOf, it is substituted.</li>
   *     <li>If remote.pushUrl starts with url.pushInsteadOf, it is not substituted.</li>
   *     <li>If remote.url starts with url.pushInsteadOf, but remote.pushUrl is given, additional push url is not added.</li>
   *   </ul>
   * </p>
   *
   * <p>
   *   TODO: if there are several matches in url sections, the longest should be applied. // currently only one is applied
   * </p>
   *
   * <p>
   *   This is according to {@code man git-config ("url.<base>.insteadOf" and "url.<base>.pushInsteadOf" sections},
   *   {@code man git-push ("URLS" section)} and the following discussions in the Git mailing list:
   *   <a href="http://article.gmane.org/gmane.comp.version-control.git/183587">insteadOf override urls and pushUrls</a>,
   *   <a href="http://thread.gmane.org/gmane.comp.version-control.git/127910">pushInsteadOf doesn't override explicit pushUrl</a>.
   * </p>
   */
  @NotNull
  private static UrlsAndPushUrls substituteUrls(@NotNull Collection<Url> urlSections, @NotNull Remote remote) {
    List<String> urls = new ArrayList<String>(remote.getUrls().size());
    Collection<String> pushUrls = new ArrayList<String>();

    // urls are substituted by insteadOf
    // if there are no pushUrls, we create a pushUrl for pushInsteadOf substitutions
    for (final String remoteUrl : remote.getUrls()) {
      boolean substituted = false;
      for (Url url : urlSections) {
        String insteadOf = url.getInsteadOf();
        String pushInsteadOf = url.getPushInsteadOf();
        // null means no entry, i.e. nothing to substitute. Empty string means substituting everything
        if (insteadOf != null && remoteUrl.startsWith(insteadOf)) {
          urls.add(substituteUrl(remoteUrl, url, insteadOf));
          substituted = true;
          break;
        }
        else if (pushInsteadOf != null && remoteUrl.startsWith(pushInsteadOf)) {
          if (remote.getPushUrls().isEmpty()) { // only if there are no explicit pushUrls
              pushUrls.add(substituteUrl(remoteUrl, url, pushInsteadOf)); // pushUrl is different
          }
          urls.add(remoteUrl);                                             // but url is left intact
          substituted = true;
          break;
        } 
      }
      if (!substituted) {
        urls.add(remoteUrl);
      }
    }

    // pushUrls are substituted only by insteadOf, not by pushInsteadOf
    for (final String remotePushUrl : remote.getPushUrls()) {
      boolean substituted = false;
      for (Url url : urlSections) {
        String insteadOf = url.getInsteadOf();
        // null means no entry, i.e. nothing to substitute. Empty string means substituting everything
        if (insteadOf != null && remotePushUrl.startsWith(insteadOf)) {
          pushUrls.add(substituteUrl(remotePushUrl, url, insteadOf));
          substituted = true;
          break;
        }
      }
      if (!substituted) {
        pushUrls.add(remotePushUrl);
      }
    }

    // if no pushUrls are explicitly defined yet via pushUrl or url.<base>.pushInsteadOf, they are the same as urls.
    if (pushUrls.isEmpty()) {
      pushUrls = new ArrayList<String>(urls);
    }

    return new UrlsAndPushUrls(urls, pushUrls);
  }
  
  private static class UrlsAndPushUrls {
    final List<String> myUrls;
    final Collection<String> myPushUrls;

    private UrlsAndPushUrls(List<String> urls, Collection<String> pushUrls) {
      myPushUrls = pushUrls;
      myUrls = urls;
    }

    public Collection<String> getPushUrls() {
      return myPushUrls;
    }

    public List<String> getUrls() {
      return myUrls;
    }
  }

  @NotNull
  private static String substituteUrl(@NotNull String remoteUrl, @NotNull Url url, @NotNull String insteadOf) {
    return url.myName + remoteUrl.substring(insteadOf.length());
  }

  @Nullable
  private static Remote parseRemoteSection(@NotNull String sectionName, @NotNull Profile.Section section, @Nullable ClassLoader classLoader) {
    RemoteBean remoteBean = section.as(RemoteBean.class, classLoader);
    Matcher matcher = REMOTE_SECTION.matcher(sectionName);
    if (matcher.matches()) {
      return new Remote(matcher.group(1), remoteBean);
    }
    LOG.error(String.format("Invalid remote section format in .git/config. sectionName: %s section: %s", sectionName, section));
    return null;
  }

  @Nullable
  private static Url parseUrlSection(@NotNull String sectionName, @NotNull Profile.Section section, @Nullable ClassLoader classLoader) {
    UrlBean urlBean = section.as(UrlBean.class, classLoader);
    Matcher matcher = URL_SECTION.matcher(sectionName);
    if (matcher.matches()) {
      return new Url(matcher.group(1), urlBean);
    }
    LOG.error(String.format("Invalid url section format in .git/config. sectionName: %s section: %s", sectionName, section));
    return null;
  }

  private static class Remote {

    private final String myName;
    private final RemoteBean myRemoteBean;

    private Remote(@NotNull String name, @NotNull RemoteBean remoteBean) {
      myRemoteBean = remoteBean;
      myName = name;
    }
    
    @NotNull
    private Collection<String> getUrls() {
      return nonNullCollection(myRemoteBean.getUrl());
    }

    @NotNull
    private Collection<String> getPushUrls() {
      return nonNullCollection(myRemoteBean.getPushUrl());
    }

    @Nullable
    // no need in wrapping null here - we check for it in #computePushSpec 
    private List<String> getPushSpec() {
      String[] push = myRemoteBean.getPush();
      return push == null ? null : Arrays.asList(push);
    }

    @NotNull
    private List<String> getFetchSpecs() {
      return Arrays.asList(notNull(myRemoteBean.getFetch()));
    }
    
  }

  private interface RemoteBean {
    @Nullable String[] getFetch();
    @Nullable String[] getPush();
    @Nullable String[] getUrl();
    @Nullable String[] getPushUrl();
  }

  private static class Url {
    private final String myName;
    private final UrlBean myUrlBean;

    private Url(String name, UrlBean urlBean) {
      myUrlBean = urlBean;
      myName = name;
    }

    @Nullable
    // null means to entry, i.e. nothing to substitute. Empty string means substituting everything
    public String getInsteadOf() {
      return myUrlBean.getInsteadOf();
    }

    @Nullable
    // null means to entry, i.e. nothing to substitute. Empty string means substituting everything
    public String getPushInsteadOf() {
      return myUrlBean.getPushInsteadOf();
    }
  }

  private interface UrlBean {
    @Nullable String getInsteadOf();
    @Nullable String getPushInsteadOf();
  }
  
  private static class BranchConfig {
    private final String myName;
    private final BranchBean myBean;

    public BranchConfig(String name, BranchBean bean) {
      myName = name;
      myBean = bean;
    }

    public String getName() {
      return myName;
    }

    public BranchBean getBean() {
      return myBean;
    }
  }
  
  private interface BranchBean {
    @Nullable String getRemote();
    @Nullable String getMerge();
    @Nullable String getRebase();
  }

  @NotNull
  private static String[] notNull(@Nullable String[] s) {
    return s == null ? ArrayUtil.EMPTY_STRING_ARRAY : s;
  }

  @NotNull
  private static Collection<String> nonNullCollection(@Nullable String[] array) {
    return array == null ? Collections.<String>emptyList() : new ArrayList<String>(Arrays.asList(array));
  }

}
