/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */

package com.sun.enterprise.cli.commands;

import com.sun.enterprise.cli.framework.*;
import com.sun.enterprise.admin.servermgmt.SMFServiceHandler;
import com.sun.enterprise.admin.servermgmt.SMFService;
import com.sun.enterprise.util.SystemPropertyConstants;
import com.sun.enterprise.admin.servermgmt.RepositoryManager;
import com.sun.enterprise.admin.servermgmt.RepositoryException;
import com.sun.enterprise.admin.servermgmt.DomainsManager;
import com.sun.enterprise.admin.servermgmt.DomainConfig;
import java.io.File;

import java.util.Date;

public class CreateServiceCommand extends S1ASCommand 
{
    private final static String TYPE = "type";
    private final static String NAME = "name";
    private final static String SERVICE_PROPERTIES = "serviceproperties";
    private final static String VALID_TYPES = "das|node-agent";
    private final static String DAS_TYPE = "das";

    /**
     *  A method that validates the options/operands 
     *  @return boolean returns true if success else returns false
     *  @throws CommandValidationException
     */
    public boolean validateOptions() throws CommandValidationException
    {
        String passwordFile = getOption(PASSWORDFILE);
        //check final the passwordfile is valid
        if (! new File(passwordFile).exists()) 
        {
            final String msg = getLocalizedString("FileDoesNotExist", 
                                                   new Object[] {passwordFile});
            throw new CommandValidationException(msg);
        }
        String typedirOperand = (String) getOperands().get(0);
        File typeDir = new File(typedirOperand);        
        String type = getOption(TYPE);
        if (!type.matches(VALID_TYPES))
        {
            throw new CommandValidationException(
                            getLocalizedString("InvalideServiceType"));
        }
        if (!typeDir.exists() || !typeDir.canWrite() || !typeDir.isDirectory()) 
        {
            final String msg = getLocalizedString("InvalidDirectory", 
                                                    new Object[] {typeDir});
            throw new CommandValidationException(msg);
        }
    	return true;
    }


    protected void validateType() throws CommandException
    {
        String typedirOperand = (String) getOperands().get(0);
        File typeDir = new File(typedirOperand);        
        String type = getOption(TYPE);
        //Validate the domain directory
        if (type.equals(DAS_TYPE))
        {
            String domainName = typeDir.getName();
            String domainRoot = typeDir.getParent();
            try {
                DomainConfig dc = new DomainConfig(domainName, domainRoot);
                RepositoryManager rm = new RepositoryManager();
                rm.checkRepository(dc, true);
            }catch (RepositoryException re){
                throw new CommandException(re.getLocalizedMessage());
            }
        }
        else // validate the node-agent directory
        {
            validateNodeAgent(typeDir);
        }
    }

    
    protected void validateNodeAgent(File typeDir) throws CommandException
    {
        throw new CommandException(getLocalizedString( "TypeNotSupported"));
    }
    
    
    /**
     *  Method that Executes the command
     *  @throws CommandException, CommandValidationException
     */
    public void runCommand() throws CommandException, CommandValidationException
    {
        validateOptions();

        validateType();

        String passwordFile = getOption(PASSWORDFILE);
        String type = getOption(TYPE);
        String typeDir = (String) getOperands().get(0);
        final SMFServiceHandler sh  = new SMFServiceHandler();
        final SMFService service = new SMFService();
        //configure service
        service.setDate(new Date().toString());
        final StringBuilder ap = new StringBuilder();
        service.setName(getName(typeDir, ap));
        service.setLocation(ap.toString());
        service.setType(type.equals("das") ? 
			SMFService.AppserverServiceType.Domain
                        : SMFService.AppserverServiceType.NodeAgent);
        service.setFQSN();
        service.setOSUser();
        service.setAsadminPath(SystemPropertyConstants.getAsAdminScriptLocation());
        service.setPasswordFilePath(passwordFile);
        service.setServiceProperties(getOption(SERVICE_PROPERTIES));
        service.isConfigValid(); 
        sh.setTrace(CLILogger.isDebug());
        sh.createService(service.tokensAndValues());
        printSuccess(service);
        CLILogger.getInstance().printMessage(getLocalizedString(
                                                   "CommandSuccessful",
                                                   new Object[] {name}));
    }

    
    /**
     *  Retrieves the domain/nodeagent name from the given directory 
     *  @return domain/nodeagent name
     *  @throws CommandValidationException
     */
    private String getName(String typeDir, final StringBuilder absolutePath) throws CommandException
    {
        String path = "";
        try
        {
            //Already checked for the valid directory in validateOptions()
           final File f = new File(typeDir);
           String name = f.getName();
           absolutePath.append(f.getAbsolutePath());
           final String nameFromOption = getOption(NAME);
           if (nameFromOption != null)
               name = nameFromOption;
           CLILogger.getInstance().printDebugMessage("service name = " + name);
           return ( name );
        }
        catch (Exception e)
        {
            throw new CommandException(e.getLocalizedMessage());
        }
    }
    private void printSuccess(final SMFService smf) {
        final String[] params = new String[] {smf.getName(), smf.getType().toString(), smf.getLocation(), smf.getManifestFilePath()};
        final String msg = getLocalizedString("SMFServiceCreated", params);
        CLILogger.getInstance().printMessage(msg);
    }
}
