package de.renew.imagenetdiff;

import java.io.File;
import java.io.PrintStream;

import CH.ifa.draw.io.DrawingFileHelper;
import CH.ifa.draw.io.StatusDisplayer;
import de.renew.draw.storables.ontology.Drawing;
import de.renew.plugin.command.CLCommand;


/**
 * Abstract base class for command-line-based diff commands in the ImageNetDiff plugin.
 * <p>
 * This class implements the {@link CLCommand} and {@link StatusDisplayer} interfaces to enable
 * diff comparisons between drawing files via the command line. It provides logic for locating
 * and loading comparable drawing files based on provided filenames (with optional extensions),
 * and delegates the actual diff operation to an associated {@link DiffExecutor}.
 *
 * @author Lawrence Cabac
 *
 */
public abstract class AbstractDiffClCommand implements CLCommand, StatusDisplayer {
    private static final org.apache.log4j.Logger LOGGER =
        org.apache.log4j.Logger.getLogger(AbstractDiffClCommand.class);
    String _command = "no name";
    DiffExecutor _diffCommand;
    final String[] _ext = { "", ".rnw", ".aip", ".draw", ".arm", ".mad" };

    /**
     *  Constructor of {@code AbstractDiffClCommand}.
     */
    public AbstractDiffClCommand() {

    }

    @Override
    public void execute(String[] args, PrintStream response) {
        int index = 0;
        boolean quiteMode = false;
        if (args.length > 0 && args[index].equals("-q")) {
            quiteMode = true;
            index++;
        }
        if (args.length - index == 0) {
            showStatus("No args gives. Synopsys: " + getName() + " [-q] file1 [file2]");
        }
        while (args.length - index >= 2) {
            String filename1 = args[index++];
            String filename2 = args[index++];
            for (String ext : _ext) {
                showStatus("Diff: trying files: " + filename1 + ext + " and " + filename2 + ext);
                File file1 = new File(filename1 + ext);
                File file2 = new File(filename2 + ext);
                if (file1.exists() && file2.exists()) {
                    Drawing drawing1 = DrawingFileHelper.loadDrawing(file1, this);
                    Drawing drawing2 = DrawingFileHelper.loadDrawing(file2, this);

                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug(
                            AbstractDiffClCommand.class.getSimpleName()
                                + ": first drawing to diff: " + drawing1.getFilename().getPath());
                        LOGGER.debug(
                            AbstractDiffClCommand.class.getSimpleName()
                                + ": second drawing to diff: " + drawing2.getFilename().getPath());
                    }
                    _diffCommand.doDiff(this, drawing1, drawing2, quiteMode);
                    break;
                } else {
                    showStatus("One or more files do not exist: " + filename1 + ", " + filename2);
                }
            }
        }
        if (args.length - index == 1) {
            String filename1 = args[index];
            for (String ext : _ext) {
                showStatus("Diff (svn base): trying file: " + filename1 + ext);
                File file1 = new File(filename1 + ext);
                if (file1.exists()) {
                    String path = file1.getParent();
                    String name = file1.getName();
                    String pathPrefix = "";
                    if (path != null) {
                        pathPrefix = path + File.separator;
                    }
                    String filename2 = pathPrefix + ".svn" + File.separator + "text-base"
                        + File.separator + name + ".svn-base";
                    File file2 = new File(filename2);
                    if (file2.exists()) {
                        Drawing drawing1 = DrawingFileHelper.loadDrawing(file1, this);
                        Drawing drawing2 = DrawingFileHelper.loadDrawing(file2, this);
                        _diffCommand.doDiff(this, drawing1, drawing2, quiteMode);
                    } else {
                        showStatus("Could not find file: " + filename2);
                    }
                    break;
                } else {
                    showStatus("File " + args[index] + ext + " does not exist.");
                }
            }
        }
    }

    /**
     * Returns the command of the class that inherits from this abstract class.
     * @return The command as a String.
     */
    protected String getName() {
        return _command;
    }

    @Override
    public void showStatus(String message) {
        LOGGER.info(message);
    }

    /**
     * @see de.renew.plugin.command.CLCommand#getArguments()
     */
    @Override
    public String getArguments() {
        return "[-q] fileNames fileNames";
    }
}