/*
 * Copyright 2012 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Eclipse Public License version 1.0, available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package org.jboss.aesh.extensions.less.aesh;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;

import org.jboss.aesh.cl.Arguments;
import org.jboss.aesh.cl.CommandDefinition;
import org.jboss.aesh.cl.Option;
import org.jboss.aesh.console.command.CommandResult;
import org.jboss.aesh.console.command.invocation.CommandInvocation;
import org.jboss.aesh.console.man.AeshFileDisplayer;
import org.jboss.aesh.console.man.FileParser;
import org.jboss.aesh.console.man.TerminalPage;
import org.jboss.aesh.extensions.page.SimpleFileParser;
import org.jboss.aesh.extensions.text.highlight.Encoder;
import org.jboss.aesh.extensions.text.highlight.Scanner;
import org.jboss.aesh.extensions.text.highlight.Syntax;
import org.jboss.aesh.io.Resource;
import org.jboss.aesh.util.ANSI;

/**
 * A less implementation for Æsh ref: http://en.wikipedia.org/wiki/Less_(Unix)
 *
 * @author <a href="mailto:stale.pedersen@jboss.org">Ståle W. Pedersen</a>
 */
@CommandDefinition(name ="less", description = "less is more")
public class Less extends AeshFileDisplayer {

    @Arguments
    List<Resource> arguments;

    @Option(hasValue = false)
    private boolean color;

    private SimpleFileParser loader;

    public Less() {
        super();
    }

    public void setFile(File file) throws IOException {
        loader.setFile(file);
    }

    public void setFile(String filename) throws IOException {
        loader.setFile(filename);
    }

    public void setInput(String input) throws IOException {
        loader.readPageAsString(input);
    }

    public void setFile(InputStream inputStream, String fileName) {
        loader.setFile(inputStream, fileName);
    }

    @Override
    public FileParser getFileParser() {
        return loader;
    }

    @Override
    public void displayBottom() throws IOException {
        if(getSearchStatus() == TerminalPage.Search.SEARCHING) {
            clearBottomLine();
           writeToConsole("/"+getSearchWord());
        }
        else if(getSearchStatus() == TerminalPage.Search.NOT_FOUND) {
            clearBottomLine();
            writeToConsole(ANSI.getInvertedBackground()+
                    "Pattern not found (press RETURN)"+
                    ANSI.defaultText());
        }
        else if(getSearchStatus() == TerminalPage.Search.RESULT) {
            writeToConsole(":");
        }
        else if(getSearchStatus() == TerminalPage.Search.NO_SEARCH) {
            if(isAtBottom())
                writeToConsole(ANSI.getInvertedBackground()+"(END)"+ANSI.defaultText());
            else
                writeToConsole(":");
        }
    }

    @Override
    public CommandResult execute(CommandInvocation commandInvocation) throws IOException, InterruptedException {
        setCommandInvocation(commandInvocation);
        //make sure to reset loader on each execute
        loader = new SimpleFileParser();
        if(commandInvocation.getShell().in().getStdIn().available() > 0) {
            java.util.Scanner s = new java.util.Scanner(commandInvocation.getShell().in().getStdIn()).useDelimiter("\\A");
            String fileContent = s.hasNext() ? s.next() : "";
            setInput(fileContent);
            afterAttach();
        }
        else if(arguments != null && arguments.size() > 0) {
            Resource f =
                    arguments.get(0).resolve(commandInvocation.getAeshContext().getCurrentWorkingDirectory()).get(0);
            if(f.isLeaf()) {
                if(color) {
                    String content = readFile(f.read());

                    ByteArrayOutputStream baos = new ByteArrayOutputStream();

                    Syntax.builtIns();
                    Syntax.Builder.create()
                            .encoderType(Encoder.Type.TERMINAL)
                            .output(baos)
                            .scanner(Scanner.Factory.byFileName(f.getName()))
                            .execute(content);

                    setInput(new String(baos.toByteArray()));
                    afterAttach();
                }
                else {
                    setFile(f.read(), f.getName());
                    afterAttach();
                }
            }
            else if(f.isDirectory()) {
                getShell().err().println(f.getAbsolutePath()+": is a directory");
            }
            else {
                getShell().err().println(f.getAbsolutePath() + ": No such file or directory");
            }
        }

        return CommandResult.SUCCESS;
    }

    private String readFile(InputStream inputStream) throws IOException {
        StringBuilder builder = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        while ((line = reader.readLine()) != null) {
            builder.append(line);
        }

        inputStream.close();

        return builder.toString();
    }
}

@@ -533,24 +533,62 @@
 .cl.Option;%0A
+import org.jboss.aesh.console.Config;%0A
 import org.j
@@ -5174,16 +5174,50 @@
 nd(line)
+.append(Config.getLineSeparator())
 ;%0A      

make sure color mode is presented correctly