/**
 * Copyright (c) 2009--2017 Red Hat, Inc.
 *
 * This software is licensed to you under the GNU General Public License,
 * version 2 (GPLv2). There is NO WARRANTY for this software, express or
 * implied, including the implied warranties of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
 * along with this software; if not, see
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 *
 * Red Hat trademarks are not licensed under GPLv2. No permission is
 * granted to use or replicate Red Hat trademarks that are incorporated
 * in this software or its documentation.
 */
package com.redhat.rhn.domain.kickstart.builder;

import com.redhat.rhn.common.conf.Config;
import com.redhat.rhn.common.conf.ConfigDefaults;
import com.redhat.rhn.common.db.datasource.DataResult;
import com.redhat.rhn.common.security.PermissionException;
import com.redhat.rhn.common.validator.ValidatorException;
import com.redhat.rhn.domain.kickstart.KickstartCommand;
import com.redhat.rhn.domain.kickstart.KickstartCommandName;
import com.redhat.rhn.domain.kickstart.KickstartData;
import com.redhat.rhn.domain.kickstart.KickstartDefaults;
import com.redhat.rhn.domain.kickstart.KickstartFactory;
import com.redhat.rhn.domain.kickstart.KickstartPackage;
import com.redhat.rhn.domain.kickstart.KickstartRawData;
import com.redhat.rhn.domain.kickstart.KickstartScript;
import com.redhat.rhn.domain.kickstart.KickstartVirtualizationType;
import com.redhat.rhn.domain.kickstart.KickstartableTree;
import com.redhat.rhn.domain.rhnpackage.PackageFactory;
import com.redhat.rhn.domain.rhnpackage.PackageName;
import com.redhat.rhn.domain.role.RoleFactory;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.frontend.action.kickstart.KickstartTreeUpdateType;
import com.redhat.rhn.frontend.dto.StringDto;
import com.redhat.rhn.frontend.xmlrpc.kickstart.InvalidVirtualizationTypeException;
import com.redhat.rhn.manager.kickstart.KickstartEditCommand;
import com.redhat.rhn.manager.kickstart.KickstartLister;
import com.redhat.rhn.manager.kickstart.KickstartScriptCreateCommand;
import com.redhat.rhn.manager.kickstart.KickstartWizardHelper;
import com.redhat.rhn.manager.kickstart.cobbler.CobblerProfileCommand;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.cobbler.Distro;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * KickstartBuilder: Creates KickstartData objects.
 * @version $Rev$
 */
public class KickstartBuilder {

    private static Logger log = Logger.getLogger(KickstartBuilder.class);

    private static final String IA64 = "IA-64";
    private static final String PPC = "PPC";
    private static final int MIN_KS_LABEL_LENGTH = 6;

    // Kickstart options frequently have multiple aliases, but we only support one version
    // in our database. This map will be used to convert to the supported version.
    private static Map<String, String> optionAliases;
    private static Set<String> installationTypes;
    private static Set<String> partitionCommands = new HashSet<String>();
    static {
        optionAliases = new HashMap<String, String>();
        optionAliases.put("authconfig", "auth");

        partitionCommands.add("logvol");
        partitionCommands.add("partition");
        partitionCommands.add("part");
        partitionCommands.add("raid");
        partitionCommands.add("volgroup");
        partitionCommands.add("%include");

        installationTypes = new HashSet<String>();
        installationTypes.add("nfs");
        installationTypes.add("url");
        installationTypes.add("cdrom");
        installationTypes.add("harddrive");
    }

    private final User user;


    /**
     * Constructor
     * @param userIn User creating the kickstart profile.
     */
    public KickstartBuilder(User userIn) {
        user = userIn;
    }

    /**
     * Create KickstartCommands and associate with their KickstartData.
     * @param ksData KickstartData to associate commands with.
     * @param lines Kickstart option lines.
     * @param tree KickstartableTree for the new kickstart profile.
     */
    public void buildCommands(KickstartData ksData, List<String> lines,
            KickstartableTree tree) {
        StringBuilder partitionBuf = new StringBuilder();
        // Grab a list of all the available command names:
        List<KickstartCommandName> availableOptions = KickstartFactory
                .lookupAllKickstartCommandNames(ksData);
        Map<String, KickstartCommandName> commandNames =
                new HashMap<String, KickstartCommandName>();
        for (KickstartCommandName cmdName : availableOptions) {
            commandNames.put(cmdName.getName(), cmdName);
        }

        Set<KickstartCommand> commandOptions = new HashSet<KickstartCommand>();

        boolean isReallyKickstartProfile = false;
        for (String currentLine : lines) {
            if (currentLine.startsWith("#") || currentLine.equals("")) {
                continue;
            }
            if (!isReallyKickstartProfile &&
                    (currentLine.trim().startsWith("<?xml") ||
                     currentLine.trim().startsWith("<!DOCTYPE") ||
                     currentLine.trim().startsWith("<!--") ||
                     currentLine.trim().startsWith("<profile"))) {
                break;
            }

            // Split the first word from the rest of the line:
            int firstSpaceIndex = currentLine.indexOf(' ');
            String firstWord = currentLine;
            String restOfLine = "";
            if (firstSpaceIndex != -1) {
                restOfLine = currentLine.substring(firstSpaceIndex).trim();
                firstWord = currentLine.substring(0, firstSpaceIndex).trim();
            }
            if (partitionCommands.contains(firstWord)) {
                partitionBuf.append(currentLine).append("\n");
                isReallyKickstartProfile = true;
                continue;
            }

            if (optionAliases.containsKey(firstWord)) {
                firstWord = optionAliases.get(firstWord);
                isReallyKickstartProfile = true;
            }

            // authconfig is an alias to the auth command
            if (firstWord.equals("authconfig")) {
                firstWord = "auth";
                isReallyKickstartProfile = true;
            }

            // Some possible values do not seem to be valid command names, (authconfig has
            // surfaced so far) what should be done with these?
            // Note: this may in fact never happen. See above, authconfig
            // is an alias to auth.
            if (!commandNames.containsKey(firstWord)) {
                // TODO
                log.warn("Unable to parse kickstart command: " + firstWord);
                continue;
            }

            // If we're to use the default URL for the new profile's kickstart tree,
            // ignore any url/nfs/cdrom/harddrive commands and instead add the default url:
            if (installationTypes.contains(firstWord)) {
                isReallyKickstartProfile = true;
                firstWord = "url";
                restOfLine = tree.getDefaultDownloadLocation();
                log.warn("Using default kickstartable tree URL:");
                log.warn("   Replaced: " + currentLine);
                log.warn("   With: " + firstWord + " " + restOfLine);
            }

            KickstartCommand kc = new KickstartCommand();
            KickstartCommandName cn = commandNames
                    .get(firstWord);
            kc.setCommandName(cn);
            kc.setKickstartData(ksData);
            kc.setCreated(new Date());
            kc.setModified(new Date());
            if (cn.getArgs().booleanValue()) {
                if (cn.getName().equals("rootpw")) {

                    // RHN only stores encrypted passwords and assumes it should add the
                    // --iscrypted option to rootpw when generating the final kickstart
                    // file. When importing we need to check for this option, remove it
                    // if it's there, and encrypt the password if it isn't.
                    // The way this works is that the system can determine from the crypted
                    // password what algorithm it was crypted with. It does not have to
                    // match with the algo specified on the auth command. So it's safe
                    // to encrypt using whatever algorithm we want without fear of being
                    // incompatible with the rest of the kickstart file.
                    String [] tokens = restOfLine.split(" ");
                    if (tokens.length > 2 || tokens.length == 0) {
                        throw new KickstartParsingException("Error parsing rootpw");
                    }
                    else if (tokens.length == 2) {
                        // Looks like the --iscrypted option is present:
                        if (!tokens[0].equals("--iscrypted")) {
                            throw new KickstartParsingException("Error parsing rootpw");
                        }
                        restOfLine = tokens[1];
                    }
                    else {
                        // No --iscrypted present, encrypt the password:
                        restOfLine = "--iscrypted " + ksData.encryptPassword(tokens[0]);
                    }
                }

                kc.setArguments(restOfLine);
            }
            commandOptions.add(kc);

        }
        ksData.setPartitionData(partitionBuf.toString());
        ksData.getCommands().addAll(commandOptions);
        KickstartFactory.saveKickstartData(ksData);
    }

    /**
     * Add packages to the given KickstartData.
     * @param ksData KickstartData to associate commands with.
     * @param lines %package section of the kickstart file.
     */
    public void buildPackages(KickstartData ksData, List<String> lines) {
        if (lines.size() == 0) {
            // Could conceivably be no packages?
            return;
        }

        // Make sure the first line starts with %packages for sanity:
        if (!(lines.get(0)).startsWith("%packages")) {
            throw new KickstartParsingException("Packages section didn't start with " +
                    "%packages tag.");
        }

        Set<KickstartPackage> ksPackagesSet = new TreeSet<KickstartPackage>();
        Long pos = 0L;
        for (Iterator<String> it = lines.iterator(); it.hasNext();) {
            String currentLine = it.next();
            if (currentLine.startsWith("#") || currentLine.startsWith("%packages") ||
                    currentLine.equals("")) {
                continue;
            }
            pos++;
            PackageName pn = PackageFactory.lookupOrCreatePackageByName(currentLine);
            ksPackagesSet.add(new KickstartPackage(ksData, pn, pos));
        }

        ksData.getKsPackages().addAll(ksPackagesSet);
    }

    /**
     * Builds the pre-scripts and associates them with the given KickstartData. Lines can
     * include multiple %pre sections.
     * @param ksData KicksartData to add scripts to.
     * @param lines %pre sections of the kickstart file.
     */
    public void buildPreScripts(KickstartData ksData, List<String> lines) {
        parseScript(ksData, lines, "%pre");
    }

    /**
     * Builds the post-scripts and associates them with the given KickstartData. Lines can
     * include multiple %post sections.
     * @param ksData KicksartData to add scripts to.
     * @param lines %post sections of the kickstart file.
     */
    public void buildPostScripts(KickstartData ksData, List<String> lines) {
        parseScript(ksData, lines, "%post");
    }

    private void parseScript(KickstartData ksData, List<String> lines, String prefix) {

        if (lines.size() == 0) {
            return;
        }

        if (!(lines.get(0)).startsWith(prefix)) {
            throw new KickstartParsingException("Pre section didn't start with " +
                    "%pre tag.");
        }

        StringBuffer buf = new StringBuffer();
        String interpreter = "";
        String chroot = "Y";
        boolean errorOnFail = false;
        for (String currentLine : lines) {
            if (currentLine.startsWith(prefix)) {
                if (buf.toString().length() > 0) {
                    storeScript(prefix, ksData, buf, interpreter, chroot, errorOnFail);
                }
                buf = new StringBuffer();

                interpreter = getInterpreter(currentLine);
                chroot = getChroot(prefix, currentLine);
                errorOnFail = getErrorOnFail(currentLine);

                continue;
            }
            if (buf.length() > 0) {
                buf.append("\n");
            }
            buf.append(currentLine);
        }
        storeScript(prefix, ksData, buf, interpreter, chroot, errorOnFail);
    }

    private String getInterpreter(String prefixLine) {
        String [] tokens = prefixLine.split(" ");
        for (int i = 1; i < tokens.length; i++) {
            if (tokens[i].equals("--interpreter")) {
                if (i == tokens.length - 1) {
                    throw new KickstartParsingException("Missing argument to " +
                            "--interpreter");
                }
                return tokens[i + 1];
            }
        }
        return null;
    }

    private String getChroot(String prefix, String prefixLine) {
        String [] tokens = prefixLine.split(" ");
        for (int i = 1; i < tokens.length; i++) {
            // nochroot is only valid for post scripts:
            if (tokens[i].equals("--nochroot")) {
                if (prefix.equals("%pre")) {
                    throw new KickstartParsingException("Invalid %pre argument: " +
                            "--nochroot");
                }
                return "N";
            }
        }
        return "Y";
    }

    private boolean getErrorOnFail(String prefixLine) {
        String[] tokens = prefixLine.split(" ");
        for (String token : tokens) {
            if (token.equals("--erroronfail")) {
                return true;
            }
        }
        return false;
    }

    private void storeScript(String prefix, KickstartData ksData, StringBuffer buf,
            String interpreter, String chroot, boolean errorOnFail) {
        KickstartScriptCreateCommand scriptCommand =
                new KickstartScriptCreateCommand(ksData.getId(), user);

        String type = KickstartScript.TYPE_PRE;
        if (prefix.equals("%post")) {
            type = KickstartScript.TYPE_POST;
        }

        scriptCommand.setScript(interpreter, buf.toString(), type, chroot, false, null,
                errorOnFail);
        scriptCommand.store();

    }

    private void checkRoles() {
        if (!user.hasRole(RoleFactory.ORG_ADMIN) &&
                !user.hasRole(RoleFactory.CONFIG_ADMIN)) {
            throw new PermissionException("Only Org Admins or Configuration Admins can " +
                    "modify kickstarts.");
        }
    }

    /**
     * Construct a KickstartData.
     * @param parser KickstartParser to build from.
     * @param label Label for the new kickstart data. (caller is responsible for ensuring
     * the label is valid and not already used within the users organization)
     * @param virtualizationType Virtualization type, or none.
     * @param tree KickstartableTree to associate with the new KickstartData.
     * @param updateType way that the profile should automaticall update the ks tree
     * @return KickstartData
     */
    public KickstartData createFromParser(KickstartParser parser, String label,
            String virtualizationType, KickstartableTree tree,
            KickstartTreeUpdateType updateType) {
        KickstartData ksdata = new KickstartData();
        setupBasicInfo(label, ksdata, tree, virtualizationType, updateType);

        if (ksdata.getKsPackages() == null) {
            ksdata.setKsPackages(new TreeSet<KickstartPackage>());
        }
        buildCommands(ksdata, parser.getOptionLines(), tree);
        buildPackages(ksdata, parser.getPackageLines());
        buildPreScripts(ksdata, parser.getPreScriptLines());
        buildPostScripts(ksdata, parser.getPostScriptLines());

        KickstartWizardHelper cmd = new KickstartWizardHelper(user);
        cmd.store(ksdata);
        return ksdata;
    }

    /**
     * Tests to see if a kickstart label is valid or not
     * @param ksLabel The label to test
     * @return true if it is valid, false otherwise
     */
    private boolean isLabelValid(String ksLabel) {
        if (ksLabel.length() < MIN_KS_LABEL_LENGTH) {
            return false;
        }
        Pattern pattern = Pattern.compile("[A-Za-z0-9_-]+", Pattern.CASE_INSENSITIVE);
        Matcher match = pattern.matcher(ksLabel);
        return match.matches();
    }

    /**
     * Checks to see if the given label aready exists
     * @param label  the Ks label
     * @return checks for duplicate labels
     */
    private KickstartData labelAlreadyExists(String label) {
        return KickstartFactory.
                lookupKickstartDataByCILabelAndOrgId(label, user.getOrg().getId());
    }

    /**
     * Checks to see if the new label meets the proper
     * criterira.
     * @param label the ks label..
     */
    public void validateNewLabel(String label) {
        if (StringUtils.isBlank(label)) {
            ValidatorException.raiseException("kickstart.details.nolabel",
                    MIN_KS_LABEL_LENGTH);
        }
        KickstartData existing = labelAlreadyExists(label);
        if (existing != null) {
            ValidatorException.raiseException("kickstart.error.labelexists",
                    existing.getLabel());
        }
        if (!isLabelValid(label)) {
            ValidatorException.raiseException("kickstart.error.invalidlabel",
                    MIN_KS_LABEL_LENGTH);
        }
    }

    /**
     * Create a new KickstartRawData object
     * basically useful for KS raw mode.
     * @param label the kickstart label
     * @param tree the Ks tree
     * @param virtType and KS virt type.
     * @param fileContents to actually write out to disk.
     * @param updateType to set for KS profile
     * @return new Kickstart Raw Data object
     */
    public KickstartRawData createRawData(String label,
            KickstartableTree tree,
            String fileContents,
            String virtType,
            KickstartTreeUpdateType updateType) {
        checkRoles();
        KickstartRawData ksdata = new KickstartRawData();
        ksdata.setData(fileContents);
        setupBasicInfo(label, ksdata, tree, virtType, updateType);
        KickstartWizardHelper cmd = new KickstartWizardHelper(user);
        cmd.store(ksdata);
        return ksdata;
    }


    private void setupBasicInfo(String ksLabel,
            KickstartData ksdata,
            KickstartableTree ksTree,
            String virtType,
            KickstartTreeUpdateType updateType) {
        checkRoles();
        validateNewLabel(ksLabel);
        ksdata.setLabel(ksLabel);
        ksdata.setOrg(user.getOrg());
        ksdata.setActive(Boolean.TRUE);
        ksdata.setOrgDefault(false);
        ksdata.setRealUpdateType(updateType);
        KickstartDefaults defaults = new KickstartDefaults();
        defaults.setKstree(ksTree);
        ksdata.setKickstartDefaults(defaults);
        defaults.setKsdata(ksdata);
        defaults.setCfgManagementFlag(Boolean.FALSE);
        defaults.setRemoteCommandFlag(Boolean.FALSE);
        setupVirtType(virtType, ksdata);
    }
    /**
     * Updates the label, tree and virty tpe infor
     * for the passed in data
     * @param data ks data
     * @param label ks label
     * @param ksTree the ks tree
     * @param virtType the virt type
     */
    public void update(KickstartData data, String label,
            KickstartableTree ksTree,
            String virtType) {
        checkRoles();
        if (!data.getLabel().equals(label)) {
            validateNewLabel(label);
            data.setLabel(label);
        }
        data.getKickstartDefaults().setKstree(ksTree);
        setupVirtType(virtType, data);
        KickstartEditCommand cmd = new KickstartEditCommand(data, user);
        cmd.store();
    }

    /**
     * sets up the virt info for a ksdata
     * @param virtType vurt type
     * @param data ksdata
     */
    private void setupVirtType(String virtType, KickstartData data) {
        if (StringUtils.isBlank(virtType)) {
            virtType = KickstartVirtualizationType.XEN_PARAVIRT;
        }
        KickstartVirtualizationType ksVirtType = KickstartFactory.
                lookupKickstartVirtualizationTypeByLabel(virtType);
        if (ksVirtType == null) {
            throw new InvalidVirtualizationTypeException(virtType);
        }
        data.getKickstartDefaults().setVirtualizationType(ksVirtType);
    }

    /**
     * Create a new KickstartData.
     *
     * @param ksLabel Label for the new kickstart profile.
     * @param tree KickstartableTree the new profile is associated with.
     * @param virtType fully_virtualized, para_virtualized, or none.
     * @param downloadUrl Download location.
     * @param rootPassword Root password.
     * @param updateType how this profile will update the kickstart tree when new ones
     * become available.
     * @return Newly created KickstartData.
     */
    public KickstartData create(String ksLabel, KickstartableTree tree,
            String virtType, String downloadUrl, String rootPassword,
            KickstartTreeUpdateType updateType) {

        checkRoles();
        KickstartData ksdata = new KickstartData();
        setupBasicInfo(ksLabel, ksdata, tree, virtType, updateType);
        KickstartCommandName kcn = null;
        KickstartCommand kscmd = null;
        ksdata.setCommands(new LinkedHashSet<KickstartCommand>());
        kcn = KickstartFactory.lookupKickstartCommandName("url");
        kscmd = new KickstartCommand();
        kscmd.setCommandName(kcn);
        kscmd.setArguments("--url " + downloadUrl);
        ksdata.getCommands().add(kscmd);
        kscmd.setKickstartData(ksdata);
        kscmd.setCreated(new Date());

        KickstartWizardHelper cmd = new KickstartWizardHelper(user);
        setNetwork(cmd, ksdata);

        setRootPassword(cmd, ksdata, rootPassword);

        // Set defaults
        setLanguage(cmd, ksdata);
        setKeyboardMouse(cmd, ksdata);
        setBootloader(cmd, ksdata);
        setTimezone(cmd, ksdata);
        setAuth(cmd, ksdata);
        setMiscDefaults(cmd, ksdata);
        setPartitionScheme(cmd, ksdata);
        cmd.processSkipKey(ksdata);
        cmd.processRepos(ksdata);
        if (ksdata.getKsPackages() == null) {
            ksdata.setKsPackages(new TreeSet<KickstartPackage>());
        }
        cmd.store(ksdata);
        return ksdata;

    }

    private void setRootPassword(KickstartWizardHelper cmd,
            KickstartData ksdata, String rootPassword) {
        cmd.createCommand("rootpw", ksdata.encryptPassword(rootPassword), ksdata);
    }

    private void setLanguage(KickstartWizardHelper cmd,
            KickstartData ksdata) {
        cmd.createCommand("lang", "en_US", ksdata);
        if (!ksdata.isRhel5OrGreater()) {
            cmd.createCommand("langsupport", "--default en_US en_US", ksdata);
        }
    }

    private void setKeyboardMouse(KickstartWizardHelper cmd,
            KickstartData ksdata) {
        cmd.createCommand("keyboard", "us", ksdata);
        if (!ksdata.isRhel5OrGreater()) {
            cmd.createCommand("mouse", "none", ksdata);
        }
    }

    private void setTimezone(KickstartWizardHelper cmd, KickstartData ksdata) {
        if (user != null && user.getTimeZone() != null) {
            StringDto userTzOlson = new StringDto(user.getTimeZone().getOlsonName());
            DataResult<StringDto> tzs =
                    KickstartLister.getInstance().getValidTimezonesFotInstallType(
                            ksdata.getTree().getInstallType());
            if (tzs.contains(userTzOlson)) {
                cmd.createCommand("timezone", userTzOlson.getValue(), ksdata);
                return;
            }
        }
        cmd.createCommand("timezone", "America/New_York", ksdata);
    }

    private void setAuth(KickstartWizardHelper cmd, KickstartData ksdata) {
        cmd.createCommand("auth", ksdata.defaultAuthArgs(), ksdata);
    }

    private void setNetwork(KickstartWizardHelper cmd, KickstartData ksdata) {
        cmd.createCommand("network", "--bootproto dhcp", ksdata);
    }

    private void setMiscDefaults(KickstartWizardHelper cmd, KickstartData ksdata) {
        if (!ksdata.isRhel5OrGreater()) {
            cmd.createCommand("zerombr", "yes", ksdata);
        }
        else {
            cmd.createCommand("zerombr", null, ksdata);
        }
        cmd.createCommand("reboot", null, ksdata);
        cmd.createCommand("skipx", null, ksdata);
        cmd.createCommand("firewall", "--disabled", ksdata);
        cmd.createCommand("clearpart", "--all", ksdata);
        if (!ksdata.isLegacyKickstart()) {
            cmd.createCommand("selinux", "--permissive", ksdata);
        }
        cmd.createCommand("text", null, ksdata);
        cmd.createCommand("install", null, ksdata);
    }

    /**
     * Setup the bootloader command for this profile's current settings.
     * @param cmd Helper
     * @param ksdata Kickstart data
     */
    public static void setBootloader(KickstartWizardHelper cmd, KickstartData ksdata) {
        if (ksdata.getKickstartDefaults().getVirtualizationType().getLabel().equals(
                KickstartVirtualizationType.XEN_PARAVIRT)) {
            cmd.createCommand("bootloader", "--location mbr --driveorder=xvda --append=",
                    ksdata);
        }
        else {
            cmd.createCommand("bootloader", "--location mbr", ksdata);
        }
    }

    /**
     * Setup the default partition scheme for this kickstart profile's current settings.
     *
     * @param cmd Helper
     * @param ksdata Kickstart data.
     */
    public static void setPartitionScheme(KickstartWizardHelper cmd, KickstartData ksdata) {

        String configData = Config.get().getString(ConfigDefaults.KS_PARTITION_DEFAULT);
        if (!StringUtils.isBlank(configData)) {
            ksdata.setPartitionData(configData);
        }
        else if (ksdata.isRhel7OrGreater()) {
            ksdata.setPartitionData("autopart --type=lvm");
        }
        else if (ksdata.getChannel().getChannelArch().getName().equals(IA64)) {
            setItaniumParitionScheme(cmd, ksdata);
        }
        else if (ksdata.getChannel().getChannelArch().getName().equals(PPC)) {
            setPpcPartitionScheme(cmd, ksdata);
        }
        else {
            String virtType = ksdata.getKickstartDefaults().
                    getVirtualizationType().getLabel();
            if (virtType.equals(KickstartVirtualizationType.XEN_PARAVIRT)) {
                String data = "part /boot --fstype ext3 --size=100 --ondisk=xvda\n" +
                        "part pv.00 --size=0 --grow --ondisk=xvda \n" +
                        "volgroup VolGroup00 --pesize=32768 pv.00\n" +
                        "logvol / --fstype ext3 --name=LogVol00 " +
                        "--vgname=VolGroup00 --size=1024 --grow\n" +
                        "logvol swap --fstype swap --name=LogVol01 " +
                        "--vgname=VolGroup00 --size=272 --grow --maxsize=544";
                ksdata.setPartitionData(data);

            }
            else if (!ksdata.isLegacyKickstart()) {
                String data = "part /boot --fstype=ext3 --size=200 \n" +
                        "part pv.01 --size=1000 --grow \n" +
                        "part swap --size=1000   --maxsize=2000 \n" +
                        "volgroup myvg pv.01 \n" +
                        "logvol / --vgname=myvg --name=rootvol --size=1000 --grow";
                ksdata.setPartitionData(data);
            }
            else {
                String data = "part /boot --fstype=ext3 --size=200 \n" +
                        "part pv.01 --size=1000 --grow \n" +
                        "part swap --size=1000   --maxsize=2000";
                ksdata.setPartitionData(data);
            }
        }
    }

    private static void setItaniumParitionScheme(KickstartWizardHelper cmd,
            KickstartData ksdata) {
        if (!ksdata.isLegacyKickstart()) {
            String data = "part /boot/efi --fstype=vfat --size=100 \n" +
                    "part swap --size=1000 --grow --maxsize=2000\n" +
                    "part pv.01 --fstype=ext3 --size=700 --grow\n" +
                    "volgroup myvg pv.01\n" +
                    "logvol --vgname=myvg --name=rootvol --size=1000 --grow";
            ksdata.setPartitionData(data);
        }
        else {
            String data = "part /boot/efi --fstype=vfat --size=100 \n" +
                    "part swap --size=1000 --grow --maxsize=2000\n" +
                    "part pv.01 --fstype=ext3 --size=700 --grow";
            ksdata.setPartitionData(data);
        }
    }

    private static void setPpcPartitionScheme(KickstartWizardHelper cmd,
            KickstartData ksdata) {
        log.debug("Adding PPC specific partition info:");
        if (!ksdata.isLegacyKickstart()) {
            String data = "part /boot --fstype=ext3 --size=200\n" +
                    "part prepboot --fstype \"PPC PReP Boot\" --size=4\n" +
                    "part swap --size=1000   --maxsize=2000 \n" +
                    "part pv.01 --size=1000 --grow \n" +
                    "volgroup myvg pv.01 \n" +
                    "logvol / --vgname=myvg --name=rootvol --size=1000 --grow";
            ksdata.setPartitionData(data);
        }
        else {
            String data = "part /boot --fstype=ext3 --size=200\n" +
                    "part prepboot --fstype \"PPC PReP Boot\" --size=4\n" +
                    "part swap --size=1000   --maxsize=2000 \n" +
                    "part / --fstype=ext3 --size=700 --grow";
            ksdata.setPartitionData(data);
        }

    }

    /**
     * Check if there is a suitable distro for tree + virt. type combination.
     * @param tree suitable kickstartable tree
     * @param virtualizationType string with virtualization type
     */
    public void validateTreeVirt(KickstartableTree tree, String virtualizationType) {
        KickstartVirtualizationType vType =
                KickstartFactory.lookupKickstartVirtualizationTypeByLabel(
                        virtualizationType);
        Distro distro = CobblerProfileCommand.getCobblerDistroForVirtType(tree,
                vType, user);
        if (distro == null) {
            ValidatorException.raiseException(
                    "kickstart.cobbler.profile.nodistribution");
        }
    }

}
