/*
 * 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.jetbrains.python.console;

import com.intellij.codeInsight.hint.HintManager;
import com.intellij.execution.console.LanguageConsoleImpl;
import com.intellij.execution.console.LanguageConsoleView;
import com.intellij.execution.console.LanguageConsoleViewImpl;
import com.intellij.execution.filters.Filter;
import com.intellij.execution.filters.HyperlinkInfo;
import com.intellij.execution.filters.OpenFileHyperlinkInfo;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.execution.ui.ObservableConsoleView;
import com.intellij.ide.GeneralSettings;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.util.ui.UIUtil;
import com.intellij.xdebugger.impl.frame.XStandaloneVariablesView;
import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.console.completion.PythonConsoleAutopopupBlockingHandler;
import com.jetbrains.python.console.pydev.ConsoleCommunication;
import com.jetbrains.python.console.pydev.ConsoleCommunicationListener;
import com.jetbrains.python.debugger.PyDebuggerEditorsProvider;
import com.jetbrains.python.debugger.PyStackFrame;
import com.jetbrains.python.debugger.PyStackFrameInfo;
import com.jetbrains.python.highlighting.PyHighlighter;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

/**
 * @author traff
 */
public class PythonConsoleView extends JPanel implements LanguageConsoleView, ObservableConsoleView, PyCodeExecutor {

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

  private final Project myProject;
  private PydevConsoleExecuteActionHandler myExecuteActionHandler;
  private PyConsoleSourceHighlighter mySourceHighlighter;
  private boolean myIsIPythonOutput = false;
  private final PyHighlighter myPyHighlighter;
  private final EditorColorsScheme myScheme;
  private boolean myHyperlink;

  private final LanguageConsoleViewImpl myLanguageConsoleView;

  private Disposable mySplitDisposable;

  public PythonConsoleView(final Project project, final String title, final Sdk sdk) {
    super(new BorderLayout());

    LanguageConsoleImpl languageConsole = new LanguageConsoleImpl(project, title, PythonLanguage.getInstance(), false);
    if (languageConsole.getFile().getVirtualFile() != null) {
      languageConsole.getFile().getVirtualFile().putUserData(LanguageLevel.KEY, PythonSdkType.getLanguageLevelForSdk(sdk));
    }
    // Mark editor as console one, to prevent autopopup completion
    languageConsole.getConsoleEditor().putUserData(PythonConsoleAutopopupBlockingHandler.REPL_KEY, new Object());
    languageConsole.setShowSeparatorLine(PyConsoleOptions.getInstance(project).isShowSeparatorLine());
    languageConsole.initComponents();

    myLanguageConsoleView = new LanguageConsoleViewImpl(languageConsole);
    Disposer.register(this, myLanguageConsoleView);

    add(myLanguageConsoleView.getComponent(), BorderLayout.CENTER);

    addSaveContentFocusListener(getLanguageConsole().getConsoleEditor().getContentComponent());

    getPythonLanguageConsole().setPrompt(PyConsoleUtil.ORDINARY_PROMPT);
    myLanguageConsoleView.setUpdateFoldingsEnabled(false);
    myProject = project;
    //noinspection ConstantConditions
    myPyHighlighter = new PyHighlighter(
      sdk != null && sdk.getVersionString() != null ? LanguageLevel.fromPythonVersion(sdk.getVersionString()) : LanguageLevel.getDefault());
    myScheme = getPythonLanguageConsole().getConsoleEditor().getColorsScheme();
  }

  public void setConsoleCommunication(final ConsoleCommunication communication) {
    getPythonLanguageConsole().getFile().putCopyableUserData(PydevConsoleRunner.CONSOLE_KEY, communication);
  }

  public void setExecutionHandler(@NotNull PydevConsoleExecuteActionHandler consoleExecuteActionHandler) {
    myExecuteActionHandler = consoleExecuteActionHandler;
  }

  private void addSaveContentFocusListener(JComponent component) {
    component.addFocusListener(new FocusListener() {
      @Override
      public void focusGained(FocusEvent e) {
        if (GeneralSettings.getInstance().isSaveOnFrameDeactivation()) {
          FileDocumentManager.getInstance().saveAllDocuments();
        }
      }

      @Override
      public void focusLost(FocusEvent e) {
      }
    });
  }

  @Override
  public void requestFocus() {
    IdeFocusManager.findInstance().requestFocus(getPythonLanguageConsole().getConsoleEditor().getContentComponent(), true);
    myLanguageConsoleView.updateUI();
    getLanguageConsole().getHistoryViewer().getComponent().updateUI();
  }

  private LanguageConsoleImpl getPythonLanguageConsole() {
    return getLanguageConsole();
  }

  public LanguageConsoleImpl getLanguageConsole() {
    return myLanguageConsoleView.getConsole();
  }

  @Override
  public void executeCode(final @NotNull String code, @Nullable final Editor editor) {
    showConsole(new Runnable() {
      @Override
      public void run() {
        ProgressManager.getInstance().run(new Task.Backgroundable(null, "Executing code in console...", false) {
          @Override
          public void run(@NotNull final ProgressIndicator indicator) {
            long time = System.currentTimeMillis();
            while (!myExecuteActionHandler.isEnabled() || !myExecuteActionHandler.canExecuteNow()) {
              if (indicator.isCanceled()) {
                break;
              }
              if (System.currentTimeMillis() - time > 1000) {
                if (editor != null) {
                  UIUtil.invokeLaterIfNeeded(new Runnable() {
                    @Override
                    public void run() {
                      HintManager.getInstance().showErrorHint(editor, myExecuteActionHandler.getCantExecuteMessage());
                    }
                  });
                }
                return;
              }
              try {
                Thread.sleep(300);
              }
              catch (InterruptedException ignored) {
              }
            }
            if (!indicator.isCanceled()) {
              doExecute(code);
            }
          }
        });
      }
    });
  }

  private void showConsole(@NotNull Runnable runnable) {
    PythonConsoleToolWindow toolWindow = PythonConsoleToolWindow.getInstance(myProject);
    if (toolWindow != null && !ApplicationManager.getApplication().isUnitTestMode()) {
      toolWindow.getToolWindow().activate(runnable);
    }
    else {
      runnable.run();
    }
  }


  private void doExecute(String code) {
    String codeFragment = PyConsoleIndentUtil.normalize(code, myExecuteActionHandler.getCurrentIndentSize());
    codeFragment += "\n";
    executeInConsole(codeFragment);
  }

  public void executeInConsole(final String code) {
    UIUtil.invokeLaterIfNeeded(new Runnable() {
      @Override
      public void run() {
        String text = getPythonLanguageConsole().getConsoleEditor().getDocument().getText();

        getPythonLanguageConsole().setInputText(code);
        myExecuteActionHandler.runExecuteAction(myLanguageConsoleView);

        if (!StringUtil.isEmpty(text)) {
          getPythonLanguageConsole().setInputText(text);
        }
      }
    });
  }

  public void executeStatement(@NotNull String statement, @NotNull final Key attributes) {
    print(statement, outputTypeForAttributes(attributes));
    myExecuteActionHandler.processLine(statement, true);
  }

  public void print(String text, @NotNull final Key attributes) {
    print(text, outputTypeForAttributes(attributes));
  }

  public void printText(String text, final ConsoleViewContentType outputType) {
    myLanguageConsoleView.print(text, outputType);
  }

  @Override
  public void print(@NotNull String text, @NotNull final ConsoleViewContentType outputType) {
    detectIPython(text, outputType);
    if (PyConsoleUtil.detectIPythonEnd(text)) {
      myIsIPythonOutput = false;
      mySourceHighlighter = null;
    }
    else if (PyConsoleUtil.detectIPythonStart(text)) {
      myIsIPythonOutput = true;
    }
    else {
      if (mySourceHighlighter == null || outputType == ConsoleViewContentType.ERROR_OUTPUT) {
        if (myHyperlink) {
          printHyperlink(text, outputType);
        }
        else {
          //Print text normally with converted attributes
          myLanguageConsoleView.print(text, outputType);
        }
        myHyperlink = detectHyperlink(text);
        if (mySourceHighlighter == null && myIsIPythonOutput && PyConsoleUtil.detectSourcePrinting(text)) {
          mySourceHighlighter = new PyConsoleSourceHighlighter(this, myScheme, myPyHighlighter);
        }
      }
      else {
        try {
          mySourceHighlighter.printHighlightedSource(text);
        }
        catch (Exception e) {
          LOG.error(e);
        }
      }
    }
  }

  @Override
  public void clear() {
    myLanguageConsoleView.clear();
  }

  @Override
  public void scrollTo(int offset) {
    myLanguageConsoleView.scrollTo(offset);
  }

  @Override
  public void attachToProcess(ProcessHandler processHandler) {
    myLanguageConsoleView.attachToProcess(processHandler);
  }

  @Override
  public void setOutputPaused(boolean value) {
    myLanguageConsoleView.setOutputPaused(value);
  }

  @Override
  public boolean isOutputPaused() {
    return myLanguageConsoleView.isOutputPaused();
  }

  @Override
  public boolean hasDeferredOutput() {
    return myLanguageConsoleView.hasDeferredOutput();
  }

  @Override
  public void performWhenNoDeferredOutput(Runnable runnable) {
    myLanguageConsoleView.performWhenNoDeferredOutput(runnable);
  }

  @Override
  public void setHelpId(String helpId) {
    myLanguageConsoleView.setHelpId(helpId);
  }

  @Override
  public void addMessageFilter(Filter filter) {
    myLanguageConsoleView.addMessageFilter(filter);
  }

  @Override
  public void printHyperlink(String hyperlinkText, HyperlinkInfo info) {
    myLanguageConsoleView.printHyperlink(hyperlinkText, info);
  }

  @Override
  public int getContentSize() {
    return myLanguageConsoleView.getContentSize();
  }

  @Override
  public boolean canPause() {
    return myLanguageConsoleView.canPause();
  }

  @NotNull
  @Override
  public AnAction[] createConsoleActions() {
    return myLanguageConsoleView.createConsoleActions();
  }

  @Override
  public void allowHeavyFilters() {
    myLanguageConsoleView.allowHeavyFilters();
  }

  public void detectIPython(String text, final ConsoleViewContentType outputType) {
    VirtualFile file = getConsoleVirtualFile();
    if (file != null) {
      if (PyConsoleUtil.detectIPythonImported(text, outputType)) {
        PyConsoleUtil.markIPython(file);
      }
      if (PyConsoleUtil.detectIPythonAutomagicOn(text)) {
        PyConsoleUtil.setIPythonAutomagic(file, true);
      }
      if (PyConsoleUtil.detectIPythonAutomagicOff(text)) {
        PyConsoleUtil.setIPythonAutomagic(file, false);
      }
    }
  }

  public VirtualFile getConsoleVirtualFile() {
    return getLanguageConsole().getFile().getVirtualFile();
  }

  private boolean detectHyperlink(@NotNull String text) {
    return myIsIPythonOutput && text.startsWith("File:");
  }

  private void printHyperlink(@NotNull String text, @NotNull ConsoleViewContentType contentType) {
    if (!StringUtil.isEmpty(text)) {
      VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(text.trim());

      if (vFile != null) {
        OpenFileHyperlinkInfo hyperlink = new OpenFileHyperlinkInfo(myProject, vFile, -1);

        myLanguageConsoleView.printHyperlink(text, hyperlink);
      }
      else {
        myLanguageConsoleView.print(text, contentType);
      }
    }
  }

  public ConsoleViewContentType outputTypeForAttributes(Key attributes) {
    final ConsoleViewContentType outputType;
    if (attributes == ProcessOutputTypes.STDERR) {
      outputType = ConsoleViewContentType.ERROR_OUTPUT;
    }
    else if (attributes == ProcessOutputTypes.SYSTEM) {
      outputType = ConsoleViewContentType.SYSTEM_OUTPUT;
    }
    else {
      outputType = ConsoleViewContentType.getConsoleViewType(attributes);
    }

    return outputType;
  }

  public void setSdk(Sdk sdk) {
    getPythonLanguageConsole().getFile().putCopyableUserData(PydevConsoleRunner.CONSOLE_SDK, sdk);
  }

  @Override
  public JComponent getComponent() {
    return this;
  }

  @Override
  public JComponent getPreferredFocusableComponent() {
    return myLanguageConsoleView.getPreferredFocusableComponent();
  }

  @Override
  public void dispose() {
    Disposer.dispose(this);
  }

  @Override
  public void addChangeListener(@NotNull ChangeListener listener, @NotNull Disposable parent) {
    myLanguageConsoleView.addChangeListener(listener, parent);
  }

  @NotNull
  @Override
  public LanguageConsoleImpl getConsole() {
    return myLanguageConsoleView.getConsole();
  }

  @NotNull
  @Override
  public Project getProject() {
    return myProject;
  }

  public void showVariables(PydevConsoleCommunication consoleCommunication) {
    PyStackFrame stackFrame = new PyStackFrame(myProject, consoleCommunication, new PyStackFrameInfo("", "", "", null), null);
    final XStandaloneVariablesView view = new XStandaloneVariablesView(myProject, new PyDebuggerEditorsProvider(), stackFrame);
    consoleCommunication.addCommunicationListener(new ConsoleCommunicationListener() {
      @Override
      public void commandExecuted(boolean more) {
        view.rebuildView();
      }

      @Override
      public void inputRequested() {
      }
    });
    splitWindow(view.getPanel(), view);
  }

  private void splitWindow(JComponent component, Disposable componentDisposable) {
    removeAll();
    JSplitPane p = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
    p.add(myLanguageConsoleView.getComponent(), JSplitPane.LEFT);
    mySplitDisposable = componentDisposable;
    p.add(component, JSplitPane.RIGHT);
    p.setDividerLocation((int)getSize().getWidth() * 2 / 3);
    add(p, BorderLayout.CENTER);

    validate();
    repaint();
  }

  public void restoreWindow() {
    removeAll();
    add(myLanguageConsoleView.getComponent(), BorderLayout.CENTER);
    validate();
    repaint();
    if (mySplitDisposable != null) {
      Disposer.dispose(mySplitDisposable);
      mySplitDisposable = null;
    }
  }
}
