// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License.  Citrix Systems, Inc.
// reserves all rights not expressly granted by the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 
// Automatically generated by addcopyright.py at 04/03/2012
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;
	}
	
}
