/*
 * Copyright 2000-2015 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.push;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.ui.GridBag;
import com.intellij.util.ui.UIUtil;
import git4idea.commands.Git;
import git4idea.commands.GitCommandResult;
import git4idea.repo.GitRemote;
import git4idea.repo.GitRepository;
import git4idea.validators.GitRefNameValidator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;

class GitDefineRemoteDialog extends DialogWrapper {

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

  @NotNull private final GitRepository myRepository;
  @NotNull private final Git myGit;

  @NotNull private final JTextField myRemoteName;
  @NotNull private final JTextField myRemoteUrl;

  GitDefineRemoteDialog(@NotNull GitRepository repository, @NotNull Git git) {
    super(repository.getProject());
    myRepository = repository;
    myGit = git;
    myRemoteName = new JTextField(GitRemote.ORIGIN_NAME, 20);
    myRemoteUrl = new JTextField(20);
    setTitle("Define Remote");
    init();
  }

  @Nullable
  @Override
  protected JComponent createCenterPanel() {
    JPanel defineRemoteComponent = new JPanel(new GridBagLayout());
    GridBag gb = new GridBag().
      setDefaultAnchor(GridBagConstraints.LINE_START).
      setDefaultInsets(UIUtil.DEFAULT_VGAP, UIUtil.DEFAULT_HGAP, 0, 0);
    defineRemoteComponent.add(new JBLabel("Name:"), gb.nextLine().next().anchor(GridBagConstraints.EAST));
    defineRemoteComponent.add(myRemoteName, gb.next());
    defineRemoteComponent.add(new JBLabel("URL: "),
                              gb.nextLine().next().anchor(GridBagConstraints.EAST).insets(0, UIUtil.DEFAULT_HGAP, UIUtil.DEFAULT_VGAP, 0));
    defineRemoteComponent.add(myRemoteUrl, gb.next());
    return defineRemoteComponent;
  }

  @NotNull
  String getRemoteName() {
    return StringUtil.notNullize(myRemoteName.getText()).trim();
  }

  @NotNull
  String getRemoteUrl() {
    return StringUtil.notNullize(myRemoteUrl.getText()).trim();
  }

  @Nullable
  @Override
  public JComponent getPreferredFocusedComponent() {
    return myRemoteUrl;
  }

  @Override
  protected void doOKAction() {
    try {
      String name = getRemoteName();
      String url = getRemoteUrl();
      String error = validateRemoteUnderModal(name, url);
      if (error != null) {
        LOG.warn(String.format("Invalid remote. Name: [%s], URL: [%s], error: %s", name, url, error));
        Messages.showErrorDialog(myRepository.getProject(), error, "Invalid Remote URL");
      }
      else {
        super.doOKAction();
      }
    }
    catch (ProcessCanceledException pce) {
      // let the dialog stay open
    }
  }

  @Nullable
  private String validateRemoteUnderModal(final String name, final String url) {
    if (url.isEmpty()) {
      return "URL can't be empty";
    }
    if (!GitRefNameValidator.getInstance().checkInput(name)) {
      return "Remote name is invalid";
    }

    return ProgressManager.getInstance().runProcessWithProgressSynchronously(new ThrowableComputable<String, ProcessCanceledException>() {
      @Override
      public String compute() throws ProcessCanceledException {
        final GitCommandResult result = myGit.lsRemote(myRepository.getProject(), VfsUtilCore.virtualToIoFile(myRepository.getRoot()), url);
        return !result.success() ? "Remote URL is invalid: " + result.getErrorOutputAsHtmlString() : null;
      }
    }, "Checking URL...", true, myRepository.getProject());
  }

}

@@ -3204,20 +3204,8 @@
 ) %7B%0A
-    try %7B%0A  
     
@@ -3231,26 +3231,24 @@
 moteName();%0A
-  
     String u
@@ -3272,18 +3272,16 @@
 ();%0A    
-  
 String e
@@ -3328,18 +3328,16 @@
 l);%0A    
- 
- 
 if (erro
@@ -3345,26 +3345,24 @@
  != null) %7B%0A
-  
       LOG.wa
@@ -3450,18 +3450,16 @@
 rror));%0A
-  
       Me
@@ -3542,22 +3542,18 @@
 %22);%0A    
-  %7D%0A  
+%7D%0A
     else
@@ -3555,18 +3555,16 @@
  else %7B%0A
-  
       su
@@ -3585,99 +3585,8 @@
 ();%0A
-      %7D%0A    %7D%0A    catch (ProcessCanceledException pce) %7B%0A      // let the dialog stay open%0A
     
@@ -3646,20 +3646,23 @@
 erModal(
-fina
+@NotNul
 l String
@@ -3667,16 +3667,25 @@
 ng name,
+ @NotNull
  final S
@@ -3694,16 +3694,48 @@
 ing url)
+ throws ProcessCanceledException
  %7B%0A    i

define remote dialog: notnull, don't catch PCE: it will be silently consumed above