/**
 * *  Copyright (C) 2011 Citrix Systems, Inc.  All rights reserved
*
 *
 * This software is licensed under the GNU General Public License v3 or later.
 *
 * It is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * 
 * This software is licensed under the GNU General Public License v3 or later.
 * 
 * It is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @author-aj
 */

package com.cloud.netapp;

import java.io.IOException;
import java.net.UnknownHostException;
import java.rmi.ServerException;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.ejb.Local;
import javax.naming.ConfigurationException;

import netapp.manage.NaAPIFailedException;
import netapp.manage.NaAuthenticationException;
import netapp.manage.NaElement;
import netapp.manage.NaException;
import netapp.manage.NaProtocolException;
import netapp.manage.NaServer;

import org.apache.log4j.Logger;

import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.netapp.dao.LunDao;
import com.cloud.netapp.dao.PoolDao;
import com.cloud.netapp.dao.VolumeDao;
import com.cloud.utils.component.Inject;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;

@Local(value = { NetappManager.class })
public class NetappManagerImpl implements NetappManager
{   
	public enum Algorithm { roundrobin,leastfull }

    protected String _name;
    
    public static final Logger s_logger = Logger.getLogger(NetappManagerImpl.class.getName());
    @Inject public VolumeDao _volumeDao;
    @Inject public PoolDao _poolDao;
    @Inject public LunDao _lunDao;
    private NetappAllocator _netappAllocator = null;
    
    /**
     * Default constructor
     */
    public NetappManagerImpl(){
    }
    
    @Override
    public  void createPool(String poolName, String algorithm) throws InvalidParameterValueException
    {	
		if(s_logger.isDebugEnabled())
			s_logger.debug("Request --> createPool ");
		
    	PoolVO pool = null;
    	validAlgorithm(algorithm);
    	try {
    		pool = new PoolVO(poolName, algorithm);
    		_poolDao.persist(pool); 
    		
    		if(s_logger.isDebugEnabled())
    			s_logger.debug("Response --> createPool:success");
    		
    	} catch (CloudRuntimeException cre){
    		pool = _poolDao.findPool(poolName);
        	if (pool != null) {
        		throw new InvalidParameterValueException("Duplicate Pool Name");
        	} else {
        		throw cre;
        	}
    	}
    }
    
    /**
     * This method validates the algorithm used for allocation of the volume
     * @param algorithm -- algorithm type
     * @throws InvalidParameterValueException
     */
    private void validAlgorithm(String algorithm) throws InvalidParameterValueException {
    	//TODO: use enum
    	if(!algorithm.equalsIgnoreCase("roundrobin") && !algorithm.equalsIgnoreCase("leastfull")){
    		throw new InvalidParameterValueException("Unknown algorithm " + algorithm);
    	}
    }
    
    /**
     * Utility method to get the netapp server object
     * @param serverIp -- ip address of netapp box
     * @param userName -- username
     * @param password -- password
     * @return
     * @throws UnknownHostException
     */
    private NaServer getServer(String serverIp, String userName, String password) throws UnknownHostException {
    	//Initialize connection to server, and
		//request version 1.3 of the API set
    	NaServer s = new NaServer(serverIp, 1, 3); 
		s.setStyle(NaServer.STYLE_LOGIN_PASSWORD);
		s.setAdminUser(userName, password); 
    	
		return s;
    }
    
    @Override
    public void modifyPool(String poolName, String algorithm) throws InvalidParameterValueException
    {	
    	validAlgorithm(algorithm);
    	PoolVO pool = _poolDao.findPool(poolName);
    	
    	if(pool == null){
    		throw new InvalidParameterValueException("Cannot find pool " + poolName);
    	}
    	
    	validAlgorithm(algorithm);
    	
    	pool.setAlgorithm(algorithm);
    	pool.setName(poolName);
    	
    	_poolDao.update(pool.getId(), pool);
    }
    
    @Override
    public void deletePool(String poolName) throws InvalidParameterValueException, ResourceInUseException
    {
		if(s_logger.isDebugEnabled())
			s_logger.debug("Request --> deletePool ");
		
    	PoolVO pool = _poolDao.findPool(poolName);
    	if(pool == null){
    		throw new InvalidParameterValueException("Cannot find pool " + poolName);
    	}
    	//check if pool is empty
    	int volCount = _volumeDao.listVolumes(poolName).size();

    	if(volCount==0){
    		_poolDao.remove(pool.getId());
		if(s_logger.isDebugEnabled())
			s_logger.debug("Request --> deletePool: Success ");
    		
    	} else {
    		throw new ResourceInUseException("Cannot delete non-empty pool");
    	}
    }
    
    @Override
    public List<PoolVO> listPools(){
    	return _poolDao.listAll();
    }
    
    /**
     * This method destroys the volume on netapp filer
     * @param ipAddress -- ip address of filer
     * @param aggrName -- name of containing aggregate
     * @param volName -- name of volume to destroy
     * @throws ResourceInUseException 
     * @throws NaException
     * @throws IOException
     * @throws NaProtocolException 
     * @throws NaAPIFailedException 
     * @throws NaAuthenticationException 
     */
    @Override
    @DB
    public void destroyVolumeOnFiler(String ipAddress, String aggrName, String volName) throws ServerException, InvalidParameterValueException, ResourceInUseException{
		NaElement xi0;
    	NaElement xi1;
 		NetappVolumeVO volume = null;
		
 		volume = _volumeDao.findVolume(ipAddress, aggrName, volName);
 		
 		if(volume==null)
 		{
 			s_logger.warn("The volume does not exist in our system");
 			throw new InvalidParameterValueException("The given tuple:"+ipAddress+","+aggrName+","+volName+" doesn't exist in our system");
 		}

 		List<LunVO> lunsOnVol = _lunDao.listLunsByVolId(volume.getId());
 		
 		if(lunsOnVol!=null && lunsOnVol.size()>0)
 		{
 			s_logger.warn("There are luns on the volume");
 			throw new ResourceInUseException("There are luns on the volume");
 		}
 		
 		final Transaction txn = Transaction.currentTxn();
 		txn.start();
 		PoolVO pool = _poolDao.findById(volume.getPoolId());
 		if (pool == null) {
 			throw new InvalidParameterValueException("Failed to find pool for given volume");
 			//FIXME: choose a better exception. this is a db integrity exception
 		}
 		pool = _poolDao.acquireInLockTable(pool.getId());
 		if (pool == null) {
 			throw new ConcurrentModificationException("Failed to acquire lock on pool " + volume.getPoolId());
 		}
		NaServer s = null;
		try 
		{
			s = getServer(volume.getIpAddress(), volume.getUsername(), volume.getPassword());
			//bring the volume down
			xi0 = new NaElement("volume-offline");
			xi0.addNewChild("name",volName);
			s.invokeElem(xi0);

			//now destroy it
			xi1 = new NaElement("volume-destroy");
			xi1.addNewChild("name",volName);
			s.invokeElem(xi1);

			//now delete from our records
			_volumeDao.remove(volume.getId());
			txn.commit();

		} catch (UnknownHostException uhe) {
			s_logger.warn("Unable to delete volume on filer " , uhe);
			throw new ServerException("Unable to delete volume on filer", uhe);
		}catch (NaAPIFailedException naf) {
			s_logger.warn("Unable to delete volume on filer " , naf);
			if( naf.getErrno() == 13040 ){
				s_logger.info("Deleting the volume: " + volName);
				_volumeDao.remove(volume.getId());
				txn.commit();
			}
			
			throw new ServerException("Unable to delete volume on filer", naf);
		} 
		catch (NaException nae) {
			txn.rollback();
			s_logger.warn("Unable to delete volume on filer " , nae);
			throw new ServerException("Unable to delete volume on filer", nae);
		} catch (IOException ioe) {
			txn.rollback();
			s_logger.warn("Unable to delete volume on filer " , ioe);
			throw new ServerException("Unable to delete volume on filer", ioe);
		}
		finally
		{
			if (pool != null) {
				_poolDao.releaseFromLockTable(pool.getId());
			}
			if (s != null)
				s.close();
		}


			
    }
    
    /**
     * This method creates a volume on netapp filer
     * @param ipAddress -- ip address of the filer
     * @param aggName -- name of aggregate
     * @param poolName -- name of pool
     * @param volName -- name of volume
     * @param volSize -- size of volume to be created
     * @param snapshotPolicy -- associated snapshot policy for volume
     * @param snapshotReservation -- associated reservation for snapshots
     * @param username -- username
     * @param password -- password
     * @throws UnknownHostException
     * @throws InvalidParameterValueException 
     */
    @Override
    @DB
	public void createVolumeOnFiler(String ipAddress, String aggName, String poolName, String volName, String volSize, String snapshotPolicy, Integer snapshotReservation, String username, String password) throws  UnknownHostException,  ServerException, InvalidParameterValueException 
	{
  
		if(s_logger.isDebugEnabled())
			s_logger.debug("Request --> createVolume "+"serverIp:"+ipAddress);
		
		boolean snapPolicy = false;
		boolean snapshotRes = false;
		boolean volumeCreated = false;
		
		NaServer s = getServer(ipAddress, username, password); 
		
		NaElement xi = new NaElement("volume-create");
		xi.addNewChild("volume", volName);
		xi.addNewChild("containing-aggr-name",aggName);
		xi.addNewChild("size",volSize);
		
		NaElement xi1 = new NaElement("snapshot-set-reserve");
		if(snapshotReservation!=null)
		{
			snapshotRes = true;
			xi1.addNewChild("percentage",snapshotReservation.toString());
			xi1.addNewChild("volume",volName);
		}
		
		NaElement xi2 = new NaElement("snapshot-set-schedule");
		
		if(snapshotPolicy!=null)
		{
			snapPolicy = true;
			
			String weeks = null;
			String days = null;
			String hours = null;
			String whichHours = null;
			String minutes = null;
			String whichMinutes = null;
			
			StringTokenizer s1 = new StringTokenizer(snapshotPolicy," ");
			
			//count=4: weeks days hours@csi mins@csi
			//count=3: weeks days hours@csi
			//count=2: weeks days
			//count=1: weeks
	
			if(s1.hasMoreTokens())
			{
				weeks = s1.nextToken();
			}
			if(weeks!=null && s1.hasMoreTokens())
			{
				days = s1.nextToken();
			}
			if(days!=null && s1.hasMoreTokens())
			{
				String[] hoursArr = s1.nextToken().split("@");
				hours = hoursArr[0];
				whichHours = hoursArr[1];
			}
			if(hours!=null && s1.hasMoreTokens())
			{
				String[] minsArr = s1.nextToken().split("@");
				minutes = minsArr[0];
				whichMinutes = minsArr[1];
			}
			
			if(weeks!=null)
				xi2.addNewChild("weeks",weeks);
			if(days!=null)
				xi2.addNewChild("days",days);
			if(hours!=null)
				xi2.addNewChild("hours",hours);
			if(minutes!=null)
				xi2.addNewChild("minutes",minutes);
			xi2.addNewChild("volume",volName);
			
			if(whichHours!=null)
				xi2.addNewChild("which-hours",whichHours);
			if(whichMinutes!=null)
				xi2.addNewChild("which-minutes",whichMinutes);
		}
		Long volumeId = null;
		
		final Transaction txn = Transaction.currentTxn();
		txn.start();
		NetappVolumeVO volume = null;
		volume = _volumeDao.findVolume(ipAddress, aggName, volName);
		
		if(volume != null) {
			throw new InvalidParameterValueException("The volume for the given ipAddress/aggregateName/volumeName tuple already exists");
		}
		PoolVO pool = _poolDao.findPool(poolName);
		if (pool == null) {
			throw new InvalidParameterValueException("Cannot find pool " + poolName);
		}
		pool = _poolDao.acquireInLockTable(pool.getId());
		if (pool == null) {
			s_logger.warn("Failed to acquire lock on pool " + poolName);
			throw new ConcurrentModificationException("Failed to acquire lock on pool " + poolName);
		}
		volume = new NetappVolumeVO(ipAddress, aggName, pool.getId(), volName, volSize, "", 0, username, password,0,pool.getName());
		volume = _volumeDao.persist(volume);
		
		volumeId = volume.getId();
		try {
			s.invokeElem(xi);
			volumeCreated = true;
			
			if(snapshotRes)
			{
				s.invokeElem(xi1);
				volume.setSnapshotReservation(snapshotReservation);
				_volumeDao.update(volumeId, volume);
			}

			if(snapPolicy)
			{
				s.invokeElem(xi2);
				volume.setSnapshotPolicy(snapshotPolicy);
				_volumeDao.update(volumeId, volume);
			}	
			txn.commit();
		} catch (NaException nae) {
			//zapi call failed, log and throw e
			s_logger.warn("Failed to create volume on the netapp filer:", nae);
			txn.rollback();
			if(volumeCreated) {
				try {
					deleteRogueVolume(volName, s);//deletes created volume on filer
				} catch (NaException e) {
					s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
					throw new ServerException("Unable to create volume via cloudtools."+"Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
				} catch (IOException e) {
					s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
					throw new ServerException("Unable to create volume via cloudtools."+"Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
				}
			}
			throw new ServerException("Unable to create volume", nae);
		} catch (IOException ioe) {
			s_logger.warn("Failed to create volume on the netapp filer:", ioe);
			txn.rollback();
			if(volumeCreated) {
				try {
					deleteRogueVolume(volName, s);//deletes created volume on filer
				} catch (NaException e) {
					s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
					throw new ServerException("Unable to create volume via cloudtools."+"Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
				} catch (IOException e) {
					s_logger.warn("Failed to cleanup created volume whilst rolling back on the netapp filer:", e);
					throw new ServerException("Unable to create volume via cloudtools."+"Failed to cleanup created volume on netapp filer whilst rolling back on the cloud db:", e);
				}
			}
			throw new ServerException("Unable to create volume", ioe);
		}
		finally{
			if (s != null) 
				s.close();
			if (pool != null) 
				_poolDao.releaseFromLockTable(pool.getId());
			
		}
	}
	
    /**
     * This method is primarily used to cleanup volume created on the netapp filer, when createVol api command fails at snapshot reservation. 
     * We roll back the db record, but the record on the netapp box still exists. We clean up that record using this helper method.
     * @param volName
     * @param s -- server reference
     * @throws NaException
     * @throws IOException
     */
    private void deleteRogueVolume(String volName, NaServer s) throws NaException, IOException {
		//bring the volume down
		NaElement xi0 = new NaElement("volume-offline");
		xi0.addNewChild("name",volName);
		s.invokeElem(xi0);

		//now destroy it
		NaElement xi1 = new NaElement("volume-destroy");
		xi1.addNewChild("name",volName);
		s.invokeElem(xi1);
    }
    
	/**
	 * This method lists all the volumes by pool name
	 * @param poolName
	 * @return -- volumes in that pool
	 */
    @Override
	public List<NetappVolumeVO> listVolumesOnFiler(String poolName){
		
    	List<NetappVolumeVO> vols = _volumeDao.listVolumesAscending(poolName);
    	
    	for(NetappVolumeVO vol : vols){
    		try {
				String snapScheduleOnFiler = returnSnapshotSchedule(vol);
				vol.setSnapshotPolicy(snapScheduleOnFiler);
				
			} catch (ServerException e) {
				s_logger.warn("Error trying to get snapshot schedule for volume"+vol.getVolumeName());
			}
    	}
		return vols;
	}

    
    /**
     * Utility method to return snapshot schedule for a volume
     * @param vol -- volume for the snapshot schedule creation
     * @return -- the snapshot schedule
     * @throws ServerException
     */
    private String returnSnapshotSchedule(NetappVolumeVO vol) throws ServerException{

		NaElement xi = new NaElement("snapshot-get-schedule");
		xi.addNewChild("volume", vol.getVolumeName());
		NaServer s = null;
		try {
			s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword());
			NaElement xo = s.invokeElem(xi);
			String weeks = xo.getChildContent("weeks");
			String days = xo.getChildContent("days");
			String hours = xo.getChildContent("hours");
			String minutes = xo.getChildContent("minutes");
			String whichHours = xo.getChildContent("which-hours");
			String whichMinutes = xo.getChildContent("which-minutes");
			
			StringBuilder sB = new StringBuilder();
			sB.append(weeks).append(" ").append(days).append(" ").append(hours).append("@").append(whichHours).append(" ").append(minutes).append("@").append(whichMinutes);
			return sB.toString();
		} catch (NaException nae) {
			s_logger.warn("Failed to get volume size ", nae);
			throw new ServerException("Failed to get volume size", nae);
		} catch (IOException ioe) {
			s_logger.warn("Failed to get volume size ", ioe);
			throw new ServerException("Failed to get volume size", ioe);
		}
		finally{
			if (s != null)
				s.close();
		}
    }
	/**
	 * This method returns the ascending order list of volumes based on their ids
	 * @param poolName -- name of pool
	 * @return -- ascending ordered list of volumes based on ids
	 */
    @Override
	public List<NetappVolumeVO> listVolumesAscending(String poolName){
		return _volumeDao.listVolumesAscending(poolName);
	}
	
	/**
	 * This method returns the available size on the volume in terms of bytes
	 * @param volName -- name of volume
	 * @param userName -- username
	 * @param password -- password
	 * @param serverIp -- ip address of filer
	 * @throws UnknownHostException 
	 * @return-- available size on the volume in terms of bytes; return -1 if volume is offline
	 * @throws ServerException
	 */
    @Override
	public long returnAvailableVolumeSize(String volName, String userName, String password, String serverIp) throws ServerException {	
		long availableSize = 0;

		NaElement xi = new NaElement("volume-list-info");
		xi.addNewChild("volume", volName);
		NaServer s = null;
		String volumeState = null;
		try {
			s = getServer(serverIp, userName, password);
			NaElement xo = s.invokeElem(xi);
			List volList = xo.getChildByName("volumes").getChildren();
			Iterator volIter = volList.iterator();
			while(volIter.hasNext()){
				NaElement volInfo=(NaElement)volIter.next();
				availableSize = volInfo.getChildLongValue("size-available", -1);
				volumeState = volInfo.getChildContent("state");
			}
			
			if (volumeState != null) {
				return volumeState.equalsIgnoreCase("online") ? availableSize : -1; //return -1 if volume is offline
			}
			else {
				//catch all
				//volume state unreported
				return -1; // as good as volume offline
			}
				
			
		} catch (NaException nae) {
			s_logger.warn("Failed to get volume size ", nae);
			throw new ServerException("Failed to get volume size", nae);
		} catch (IOException ioe) {
			s_logger.warn("Failed to get volume size ", ioe);
			throw new ServerException("Failed to get volume size", ioe);
		}
		finally{
			if (s != null)
				s.close();
		}
	}

	/**
	 * This method creates a lun on the netapp filer
	 * @param poolName -- name of the pool
	 * @param lunSize -- size of the lun to be created
	 * @return -- lun path 
	 * @throws IOException
	 * @throws ResourceAllocationException 
	 * @throws NaException
	 */
    @Override
    @DB
	public String[] createLunOnFiler(String poolName, Long lunSize) throws  ServerException, InvalidParameterValueException, ResourceAllocationException {
    	String[] result = new String[3];
		StringBuilder lunName = new StringBuilder("lun-");
		LunVO lun = null;
    	final Transaction txn = Transaction.currentTxn();
		txn.start();
    	PoolVO pool = _poolDao.findPool(poolName);
    	
    	if(pool == null){
    		throw new InvalidParameterValueException("Cannot find pool " + poolName);
    	}

    	if (lunSize <= 0) {
    		throw new InvalidParameterValueException("Please specify a valid lun size in Gb");
    	}
    	
    	String algorithm = pool.getAlgorithm();
    	NetappVolumeVO selectedVol = null;

    	//sanity check
    	int numVolsInPool = _volumeDao.listVolumes(poolName).size();

    	if (numVolsInPool == 0)
    	{
    		throw new InvalidParameterValueException("No volumes exist in the given pool");
    	}
    	pool = _poolDao.acquireInLockTable(pool.getId());
    	if (pool == null) {
    		s_logger.warn("Failed to acquire lock on the pool " + poolName);
    		return result;
    	}
    	NaServer s = null;

    	try 
    	{
    		if(algorithm == null || algorithm.equals(Algorithm.roundrobin.toString()))
    		{
    			selectedVol = _netappAllocator.chooseVolumeFromPool(poolName, lunSize);
    		}
    		else if(algorithm.equals(Algorithm.leastfull.toString()))
    		{

    			selectedVol = _netappAllocator.chooseLeastFullVolumeFromPool(poolName, lunSize);
    		}

    		if(selectedVol == null)
    		{
    			throw new ServerException("Could not find a suitable volume to create lun on");
    		}

    		if(s_logger.isDebugEnabled())
    			s_logger.debug("Request --> createLun "+"serverIp:"+selectedVol.getIpAddress());
    		
    		StringBuilder exportPath = new StringBuilder("/vol/");
    		exportPath.append(selectedVol.getVolumeName());
    		exportPath.append("/");

    		lun = new LunVO(exportPath.toString(), selectedVol.getId(), lunSize, "","");
    		lun = _lunDao.persist(lun);
    		
    		//Lun id created: 6 digits right justified eg. 000045
    		String lunIdStr = lun.getId().toString();
    		String zeroStr = "000000";
    		int length = lunIdStr.length();
    		int offset = 6-length;
    		StringBuilder lunIdOnPath = new StringBuilder();
    		lunIdOnPath.append(zeroStr.substring(0, offset));
    		lunIdOnPath.append(lunIdStr);
    		exportPath.append("lun-").append(lunIdOnPath.toString());
    		
    		lunName.append(lunIdOnPath.toString());
    		
    		//update lun name
    		lun.setLunName(lunName.toString());
    		_lunDao.update(lun.getId(), lun);
    		
    		NaElement xi;
    		NaElement xi1;

    		long lSizeBytes = 1L*lunSize*1024*1024*1024; //This prevents integer overflow
    		Long lunSizeBytes = new Long(lSizeBytes);
    		
    		s = getServer(selectedVol.getIpAddress(), selectedVol.getUsername(),selectedVol.getPassword()); 

    		//create lun
    		xi = new NaElement("lun-create-by-size");
    		xi.addNewChild("ostype","linux");
    		xi.addNewChild("path",exportPath.toString());
    		xi.addNewChild("size", (lunSizeBytes.toString()));
    		
    		s.invokeElem(xi);	

    		try
    		{
	    		//now create an igroup
				xi1 = new NaElement("igroup-create");
				xi1.addNewChild("initiator-group-name", lunName .toString());
				xi1.addNewChild("initiator-group-type", "iscsi");
				xi1.addNewChild("os-type", "linux");
				s.invokeElem(xi1);
    		}catch(NaAPIFailedException e)
    		{
    			if(e.getErrno() == 9004)
    			{
    				//igroup already exists hence no error
    				s_logger.warn("Igroup already exists");
    			}
    		}

    		//get target iqn
			NaElement xi4 = new NaElement("iscsi-node-get-name");
			NaElement xo = s.invokeElem(xi4);
			String iqn = xo.getChildContent("node-name");
			
			lun.setTargetIqn(iqn);
			_lunDao.update(lun.getId(), lun);
			
			//create lun mapping
			//now map the lun to the igroup
			NaElement xi3 = new NaElement("lun-map");
			xi3.addNewChild("force", "true");
			xi3.addNewChild("initiator-group", lunName.toString());
			xi3.addNewChild("path", lun.getPath() + lun.getLunName());
			
			xi3.addNewChild("lun-id", lunIdStr);
			s.invokeElem(xi3);
    		
    		txn.commit();
    		//set the result
    		result[0] = lunName.toString();//lunname
    		result[1] = iqn;//iqn
    		result[2] =  selectedVol.getIpAddress();
    		
    		return result;
    		
    	}
    	catch (NaAPIFailedException naf)
    	{
			if(naf.getErrno() == 9023){ //lun is already mapped to this group
				result[0] = lunName.toString();//lunname;
				result[1] = lun.getTargetIqn();//iqn
				result[2] = selectedVol.getIpAddress();
				return result;
			}			
			if(naf.getErrno() == 9024){ //another lun mapped at this group
				result[0] = lunName.toString();//lunname;
				result[1] = lun.getTargetIqn();//iqn
				result[2] = selectedVol.getIpAddress();
				return result;
			}	
    	}
    	catch (NaException nae) 
    	{
    		txn.rollback();
    		throw new ServerException("Unable to create LUN", nae);
    	} 
    	catch (IOException ioe) 
    	{
    		txn.rollback();
    		throw new ServerException("Unable to create LUN", ioe);
    	}
    	finally
    	{
    		if (pool != null) {
    			_poolDao.releaseFromLockTable(pool.getId());
    		}
    		if (s != null) {
    			s.close();
    		}
    	}

    	return result;
	}
	
	/**
	 * This method destroys a lun on the netapp filer
	 * @param lunName -- name of the lun to be destroyed
	 */
    @Override
    @DB
	public void destroyLunOnFiler(String lunName) throws InvalidParameterValueException, ServerException{
		
		final Transaction txn = Transaction.currentTxn();
		txn.start();
		
		LunVO lun = _lunDao.findByName(lunName);
		
		if(lun == null)
			throw new InvalidParameterValueException("Cannot find lun");
		
		NetappVolumeVO vol = _volumeDao.acquireInLockTable(lun.getVolumeId());
		if (vol == null) {
			s_logger.warn("Failed to lock volume id= " + lun.getVolumeId());
			return;
		}
		NaServer s = null;
		try {
			s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword()); 
			
			if(s_logger.isDebugEnabled())
				s_logger.debug("Request --> destroyLun "+":serverIp:"+vol.getIpAddress());
			
			try {
				//Unmap lun
				NaElement xi2 = new NaElement("lun-unmap");
				xi2.addNewChild("initiator-group", lunName);
				xi2.addNewChild("path", lun.getPath()+lun.getLunName());
				s.invokeElem(xi2);
			} catch (NaAPIFailedException naf) {
				if(naf.getErrno()==9016)
					s_logger.warn("no map exists excpn 9016 caught in deletelun, continuing with delete");
			}

			//destroy lun
			NaElement xi = new NaElement("lun-destroy");
			xi.addNewChild("force","true");
			xi.addNewChild("path", lun.getPath()+lun.getLunName());
			s.invokeElem(xi);
			
			//destroy igroup
			NaElement xi1 = new NaElement("igroup-destroy");
			//xi1.addNewChild("force","true");
			xi1.addNewChild("initiator-group-name",lunName);
			s.invokeElem(xi1);
			
			_lunDao.remove(lun.getId());
			txn.commit();
		} catch(UnknownHostException uhe) {
			txn.rollback();
			s_logger.warn("Failed to delete lun", uhe);
			throw new ServerException("Failed to delete lun", uhe);
		} catch ( IOException ioe) {
			txn.rollback();
			s_logger.warn("Failed to delete lun", ioe);
			throw new ServerException("Failed to delete lun", ioe);
		}catch (NaAPIFailedException naf) {
			if(naf.getErrno() == 9017){//no such group exists excpn
				s_logger.warn("no such group exists excpn 9017 caught in deletelun, continuing with delete");
				_lunDao.remove(lun.getId());
				txn.commit();
			}else if(naf.getErrno() == 9029){//LUN maps for this initiator group exist
				s_logger.warn("LUN maps for this initiator group exist errno 9029 caught in deletelun, continuing with delete");
				_lunDao.remove(lun.getId());
				txn.commit();
			}else{
				txn.rollback();
				s_logger.warn("Failed to delete lun", naf);
				throw new ServerException("Failed to delete lun", naf);
			}

		} 
		catch (NaException nae) {
			txn.rollback();
			s_logger.warn("Failed to delete lun", nae);
			throw new ServerException("Failed to delete lun", nae);
		}
		finally{
			if (vol != null) {
				_volumeDao.releaseFromLockTable(vol.getId());
			}
			if (s != null)
				s.close();
		}

	}
	
	/**
	 * This method lists the luns on the netapp filer
	 * @param volId -- id of the containing volume
	 * @return -- list of netapp luns
	 * @throws NaException
	 * @throws IOException
	 */
    @Override
    public List<LunVO> listLunsOnFiler(String poolName)
	{
		if(s_logger.isDebugEnabled())
			s_logger.debug("Request --> listLunsOnFiler ");
		
    	List<LunVO> luns = new ArrayList<LunVO>();
    	
    	List<NetappVolumeVO> vols = _volumeDao.listVolumes(poolName);
    	
    	for(NetappVolumeVO vol : vols)
    	{
    		luns.addAll(_lunDao.listLunsByVolId(vol.getId()));
    	}
    
		if(s_logger.isDebugEnabled())
			s_logger.debug("Response --> listLunsOnFiler:success");
    	
    	return luns;
	}
	

	/**
	 * This method disassociates a lun from the igroup on the filer
	 * @param iGroup -- igroup name
	 * @param lunName -- lun name
	 */
    @Override
	public void disassociateLun(String iGroup, String lunName) throws ServerException, InvalidParameterValueException
	{
		NaElement xi;
		LunVO lun = _lunDao.findByName(lunName);
		
		if(lun == null)
			throw new InvalidParameterValueException("Cannot find LUN " + lunName);
		
		NetappVolumeVO vol = _volumeDao.findById(lun.getVolumeId());
		NaServer s = null;
		try {
			s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword());
			
			if(s_logger.isDebugEnabled())
				s_logger.debug("Request --> disassociateLun "+":serverIp:"+vol.getIpAddress());
			
			xi = new NaElement("igroup-remove");
			xi.addNewChild("force", "true");
			xi.addNewChild("initiator", iGroup);
			xi.addNewChild("initiator-group-name", lunName);		
			s.invokeElem(xi);
			
		} catch(UnknownHostException uhe) {
			throw new ServerException("Failed to disassociate lun", uhe);
		} catch ( IOException ioe) {
			throw new ServerException("Failed to disassociate lun", ioe);
		} catch (NaException nae) {
			throw new ServerException("Failed to disassociate lun", nae);
		} finally{
			if (s != null)
				s.close();
		}
		
	}
	
	/**
	 * This method associates a lun to a particular igroup
	 * @param iqn
	 * @param iGroup
	 * @param lunName
	 */
    @Override
	public String[] associateLun(String guestIqn, String lunName) throws ServerException, InvalidParameterValueException

	{
		NaElement xi2;

		//get lun id from path
		String[] splitLunName = lunName.split("-");
		String[] returnVal = new String[3];
		if(splitLunName.length != 2)
			throw new InvalidParameterValueException("The lun id is malformed");
		
		String lunIdStr = splitLunName[1]; 

		Long lId = new Long(lunIdStr);
		
		LunVO lun = _lunDao.findById(lId);
		
		if(lun == null)
			throw new InvalidParameterValueException("Cannot find LUN " + lunName);
		
		NetappVolumeVO vol = _volumeDao.findById(lun.getVolumeId());

		//assert(vol != null);
		
		returnVal[0] = lunIdStr;
		returnVal[1] = lun.getTargetIqn();
		returnVal[2] = vol.getIpAddress();
		
		NaServer s = null;
		
		try
		{
			s = getServer(vol.getIpAddress(), vol.getUsername(), vol.getPassword()); 
			
			if(s_logger.isDebugEnabled())
				s_logger.debug("Request --> associateLun "+":serverIp:"+vol.getIpAddress());
			
			//add iqn to the group
			xi2 = new NaElement("igroup-add");
			xi2.addNewChild("force", "true");
			xi2.addNewChild("initiator", guestIqn);
			xi2.addNewChild("initiator-group-name", lunName);		
			s.invokeElem(xi2);
						
			return returnVal;
		}  catch (UnknownHostException uhe) {
			s_logger.warn("Unable to associate LUN " , uhe);
			throw new ServerException("Unable to associate LUN", uhe);
		}catch (NaAPIFailedException naf){
			if(naf.getErrno() == 9008){ //initiator group already contains node				
				return returnVal;
			}			
			s_logger.warn("Unable to associate LUN " , naf);
			throw new ServerException("Unable to associate LUN", naf);
		}
		catch (NaException nae) {
			s_logger.warn("Unable to associate LUN " , nae);
			throw new ServerException("Unable to associate LUN", nae);
		} catch (IOException ioe) {
			s_logger.warn("Unable to associate LUN " , ioe);
			throw new ServerException("Unable to associate LUN", ioe);
		}
		finally{
			if (s != null)
				s.close();
		}
		
	}

	@Override
	public boolean configure(String name, Map<String, Object> params)
			throws ConfigurationException {

       _name = name;
       
       _netappAllocator = new NetappDefaultAllocatorImpl( this );

		return true;
	}

	@Override
	public String getName() {
		return _name;
	}

	@Override
	public boolean start() {
		return true;
	}

	@Override
	public boolean stop() {
		return true;
	}
	
}
