package com.jscape.inet.scp.protocol.marshaling;

import com.jscape.inet.scp.protocol.messages.*;
import com.jscape.util.Wildcard;

import java.io.IOException;

/**
 * @author Alex Usun
 */
public class CommandFormat {

    public static Command parse(String data)
            throws IOException {
        CommandLine commandLine = CommandLineFormat.parse(data);
        boolean preserveFileAttributes = commandLine.contains(CommandOption.PRESERVE_FILE_ATTRIBUTES);

        if (commandLine.contains(CommandOption.READ)) {
            return Wildcard.isWildcard(commandLine.path)
                   ? new ReadFilesCommand(commandLine.path, preserveFileAttributes)
                   : commandLine.contains(CommandOption.RECURSIVE) ? new ReadDirectoryCommand(commandLine.path, preserveFileAttributes) : new ReadFileCommand(commandLine.path, preserveFileAttributes);
        } else if (commandLine.contains(CommandOption.WRITE)) {
            return commandLine.contains(CommandOption.RECURSIVE) || commandLine.contains(CommandOption.TARGET_DIRECTORY)
                   ? new WriteDirectoryCommand(commandLine.path, preserveFileAttributes)
                   : new WriteFileCommand(commandLine.path, preserveFileAttributes);
        }

        throw new IOException("Unsupported command line: " + commandLine);
    }

    public static String format(Command value)
            throws IOException {
        CommandLine commandLine = commandLineFor(value);
        return CommandLineFormat.format(commandLine, true);
    }

    private static CommandLine commandLineFor(Command value)
            throws IOException {
        if (value instanceof ReadFileCommand) {
            ReadFileCommand command = (ReadFileCommand) value;
            return new CommandLine(command.path, CommandOption.READ, command.preserveAttributes ? CommandOption.PRESERVE_FILE_ATTRIBUTES : null);
        } else if (value instanceof ReadFilesCommand) {
            ReadFilesCommand command = (ReadFilesCommand) value;
            return new CommandLine(command.path, CommandOption.READ, command.preserveAttributes ? CommandOption.PRESERVE_FILE_ATTRIBUTES : null);
        } else if (value instanceof ReadDirectoryCommand) {
            ReadDirectoryCommand command = (ReadDirectoryCommand) value;
            return new CommandLine(command.path, CommandOption.READ, CommandOption.RECURSIVE, command.preserveAttributes ? CommandOption.PRESERVE_FILE_ATTRIBUTES : null);
        } else if (value instanceof WriteFileCommand) {
            WriteFileCommand command = (WriteFileCommand) value;
            return new CommandLine(command.path, CommandOption.WRITE, command.preserveAttributes ? CommandOption.PRESERVE_FILE_ATTRIBUTES : null);
        } else if (value instanceof WriteDirectoryCommand) {
            WriteDirectoryCommand command = (WriteDirectoryCommand) value;
            return new CommandLine(command.path, CommandOption.WRITE, CommandOption.RECURSIVE, command.preserveAttributes ? CommandOption.PRESERVE_FILE_ATTRIBUTES : null);
        }

        throw new IOException("Unsupported command: " + value);
    }

    private CommandFormat() {
    }
}
