/*
 * Copyright (c) 2019 Ed Merks (Beralin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Ed Merks - initial API and implementation
 */
package org.eclipse.oomph.gitbash.repository;

import org.eclipse.oomph.gitbash.AbstractAction;
import org.eclipse.oomph.util.IOUtil;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ResetCommand;
import org.eclipse.jgit.api.ResetCommand.ResetType;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.CoreConfig.AutoCRLF;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;

@SuppressWarnings("nls")
public class FixCRLFAction extends AbstractAction<Repository>
{
  private Dialog dialog;

  private Text text;

  public FixCRLFAction()
  {
    super(Repository.class);
  }

  @SuppressWarnings("restriction")
  @Override
  protected void run(Shell shell, Repository repository)
  {
    createDialog(shell);

    int fixCount = 0;

    ProgressMonitor monitor = new ProgressMonitor()
    {
      public void update(int completed)
      {
        processDisplay();
      }

      public void start(int totalTasks)
      {
        processDisplay();
      }

      public boolean isCancelled()
      {
        processDisplay();
        return false;
      }

      public void endTask()
      {
        processDisplay();
      }

      public void beginTask(String title, int totalWork)
      {
        processDisplay();
      }
    };

    Repository targetRepository = null;
    try
    {
      File directory = repository.getDirectory();
      File workTree = repository.getWorkTree();

      log("Processing " + workTree);

      File targetWorkTree = new File(workTree.getPath() + ".fix.crlf");
      if (!targetWorkTree.mkdir())
      {
        log("Failed to create target folder:" + targetWorkTree);
      }
      else
      {
        File targetDirectory = new File(targetWorkTree, ".git");
        log("Copying " + directory + " to " + targetDirectory);
        IOUtil.copyTree(directory, targetDirectory);

        log("Opening Git repository " + targetDirectory);
        Git git = Git.open(targetDirectory);
        targetRepository = git.getRepository();

        log("Configuring AutoCRL to false " + targetDirectory);
        StoredConfig config = targetRepository.getConfig();
        config.setEnum(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_AUTOCRLF, AutoCRLF.FALSE);
        config.save();

        log("Resetting to create the working tree " + targetDirectory);
        ResetCommand resetCommand = new ResetCommand(targetRepository);
        resetCommand.setProgressMonitor(monitor);
        resetCommand.setMode(ResetType.HARD);
        resetCommand.call();

        log("Visiting tree " + targetDirectory);
        for (FileTreeIterator fileTreeIterator = new FileTreeIterator(targetRepository); !fileTreeIterator.eof(); fileTreeIterator.next(1))
        {
          fixCount += visit(fileTreeIterator.getEntryFile());
        }

        git.status().call();

      }
    }
    catch (Exception ex)
    {
      log("Failure");
      StringWriter out = new StringWriter();
      PrintWriter stackTrace = new PrintWriter(out);
      ex.printStackTrace(stackTrace);
      stackTrace.close();
      log(out.toString());
      return;
    }
    finally
    {
      if (targetRepository != null)
      {
        log("Adding to repository view " + targetRepository.getWorkTree());
        org.eclipse.egit.core.RepositoryUtil repositoryUtil = org.eclipse.egit.core.RepositoryUtil.getInstance();
        repositoryUtil.addConfiguredRepository(targetRepository.getDirectory());
        targetRepository.close();
      }
    }

    if (fixCount == 0)
    {
      log("Done");
      log("No files needed fixing");
    }
    else
    {
      log(fixCount + " files fixed");
    }
  }

  private void log(final String message)
  {
    text.append(message + "\n");
    processDisplay();
  }

  private void processDisplay()
  {
    while (text.getDisplay().readAndDispatch())
    {
    }
  }

  private void createDialog(Shell shell)
  {
    final Point size = shell.getSize();
    dialog = new Dialog(shell)
    {
      @Override
      protected void configureShell(Shell newShell)
      {
        super.configureShell(newShell);
        newShell.setText("Fix CRLF");
      }

      @Override
      protected Control createDialogArea(Composite parent)
      {
        Composite composite = (Composite)super.createDialogArea(parent);
        text = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
        GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        gridData.widthHint = size.x / 2;
        gridData.heightHint = size.y / 2;
        text.setLayoutData(gridData);
        return composite;
      }
    };

    dialog.setBlockOnOpen(false);
    dialog.open();
  }

  private int visit(File file)
  {
    int result = 0;
    if (file.isDirectory())
    {
      for (File child : file.listFiles())
      {
        result += visit(child);
      }
    }
    else
    {
      byte[] bytes = IOUtil.readFile(file);
      if (RawText.isBinary(bytes))
      {
        log("Ignoring binary " + file);
      }
      else
      {
        boolean modified = false;
        ByteArrayOutputStream out = new ByteArrayOutputStream(bytes.length);
        for (int i = 0; i < bytes.length; i++)
        {
          byte b = bytes[i];
          if (b == '\r' && i + 1 < bytes.length && bytes[i + 1] == '\n')
          {
            out.write('\n');
            ++i;
            modified = true;
            continue;
          }

          out.write(b);
        }

        if (modified)
        {
          log("Fixing " + file);
          ++result;
          IOUtil.writeFile(file, out.toByteArray());
        }
      }
    }

    return result;
  }
}
