package org.asteriskjava.pbx.internal.core;

import org.apache.log4j.Logger;
import org.asteriskjava.pbx.EndPoint;
import org.asteriskjava.pbx.Trunk;

public class EndPointImpl implements EndPoint
{
    private static final String DELIMITER = "/"; //$NON-NLS-1$

    @SuppressWarnings("unused")
    private static final Logger logger = Logger.getLogger(EndPointImpl.class);

    final private TechType _tech;

    final private String _endPointName;

    final private String _fullyQualifiedName;

    // If true then this is an empty end point e.g. blank name and unknown tech.
    final private boolean _empty;

    private Trunk _trunk;

    /**
     * Creates a EndPoint from a fully qualified peer name of the form: SIP/NNN
     * LOCAL/NNN TODO: the tech encoding should probably be specific to a
     * particular pbx Implementation.
     * 
     * @param fullyQualifiedPeerName
     */
    public EndPointImpl(final String fullyQualifiedEndPoint)
    {
        if (fullyQualifiedEndPoint == null)
        {
            throw new IllegalArgumentException("The fullyQualifiedEndPoint may not be null"); //$NON-NLS-1$
        }

        final String cleaned = this.clean(fullyQualifiedEndPoint);
        this._tech = TechType.getTech(cleaned);
        this._endPointName = cleaned.substring(this._tech.name().length() + 1);

        if (this._tech == TechType.DIALPLAN)
        {
            this._fullyQualifiedName = this._endPointName;
        }
        else
        {
            this._fullyQualifiedName = this._tech.name() + EndPointImpl.DELIMITER + this._endPointName;
        }
        this._empty = false;
    }

    /**
     * Creates a empty end point.
     */
    public EndPointImpl()
    {
        this._empty = true;
        this._tech = TechType.UNKNOWN;
        this._endPointName = "";
        this._fullyQualifiedName = "";
    }

    /**
     * Creates an EndPoint from from a simple endpoint name and a tech.
     * 
     * @param _tech
     * @param peerName
     */
    // EndPoint(String endPointName, String tech)
    // {
    // if (endPointName == null)
    // throw new IllegalArgumentException("The endPoint Name may not be null");
    //
    // if (tech == null)
    // throw new IllegalArgumentException("The endPoint Tehc may not be null");
    //
    // String cleaned = clean(endPointName);
    // // Tech must be upper case to match the enum but
    // // the simple name must be lower case to matcht the context extension
    // // names.
    // this.tech = Tech.valueOf(tech.toUpperCase());
    // this.endPointName = cleaned;
    // }

    public EndPointImpl(final TechType defaultTech, final String endPointName)
    {
        if (endPointName == null)
        {
            throw new IllegalArgumentException("The endPointName may not be null"); //$NON-NLS-1$
        }

        final String cleaned = this.clean(endPointName);

        if (cleaned.length() == 0)
        {
            throw new IllegalArgumentException("The endPointName may not be empty"); //$NON-NLS-1$
        }

        // If tech is unknown then attempt to extract the tech from the
        // endPointName.
        if (TechType.hasTech(cleaned))
        {
            this._tech = TechType.getTech(cleaned);
            this._endPointName = cleaned.substring(this._tech.name().length() + 1);

        }
        else
        {
            this._tech = defaultTech;
            this._endPointName = cleaned;
        }

        if (this._tech == TechType.DIALPLAN)
        {
            this._fullyQualifiedName = this._endPointName;
        }
        else
        {
            this._fullyQualifiedName = this._tech.name() + EndPointImpl.DELIMITER + this._endPointName;
        }
        this._empty = false;
    }

    public EndPointImpl(TechType defaultTech, Trunk trunk, String endPointName)
    {
        if (endPointName == null)
        {
            throw new IllegalArgumentException("The endPointName may not be null"); //$NON-NLS-1$
        }

        final String cleaned = this.clean(endPointName);

        if (cleaned.length() == 0)
        {
            throw new IllegalArgumentException("The endPointName may not be empty"); //$NON-NLS-1$
        }

        // If tech is unknown then attempt to extract the tech from the
        // endPointName.
        if (TechType.hasTech(cleaned))
        {
            throw new IllegalArgumentException("endPointName may not contain a Tech");

        }

        this._tech = defaultTech;
        this._endPointName = cleaned;
        this._trunk = trunk;

        if (this._tech == TechType.DIALPLAN || this._tech == TechType.CONSOLE || this._tech == TechType.LOCAL)
        {
            throw new IllegalArgumentException("defaultTech may not be DIALPLAN, LOCAL or CONSOLE");
        }

        this._fullyQualifiedName = this._tech.name() + EndPointImpl.DELIMITER + trunk + EndPointImpl.DELIMITER
                + this._endPointName;

        this._empty = false;

    }

    /**
     * Returns the fully qualified endPoint.
     */
    @Override
    public String getFullyQualifiedName()
    {
        return this._fullyQualifiedName;
    }

    public Trunk getTrunk()
    {
        return _trunk;
    }

    @Override
    public boolean isSame(final EndPoint rhs)
    {
        return this.compareTo(rhs) == 0;
    }

    @Override
    public int compareTo(EndPoint rhs)
    {
        return this.getFullyQualifiedName().compareTo(rhs.getFullyQualifiedName());
    }

    @Override
    public boolean isLocal()
    {
        return this._tech == TechType.LOCAL;
    }

    /**
     * For the purposes of asterisk IAX and SIP are both considered SIP.
     */
    @Override
    public boolean isSIP()
    {
        return this._tech == TechType.SIP || this._tech == TechType.IAX || this._tech == TechType.IAX2;
    }

    public boolean isDAHDI()
    {
        return this._tech == TechType.DAHDI;
    }

    @Override
    public String getSimpleName()
    {
        return this._endPointName;
    }

    @Override
    public boolean isUnknown()
    {
        return this._tech == TechType.UNKNOWN;
    }

    /**
     * Cleans up an endpoint name by removing all whitespace (including internal
     * whitespace) as well as making the string lower case.
     * 
     * @param _endPointName
     * @return
     */
    private String clean(final String _endPointName)
    {
        String localTo = _endPointName.trim();

        // strip all white space from within the name as some source
        // pass in a formatted phone number (e.g. 03 8320 8100)
        int tmp = localTo.indexOf(" "); //$NON-NLS-1$
        while (tmp != -1)
        {
            localTo = localTo.substring(0, tmp) + localTo.substring(tmp + 1, localTo.length());
            tmp = localTo.indexOf(" "); //$NON-NLS-1$
        }
        return localTo.toLowerCase();
    }

    @Override
    public TechType getTech()
    {
        return this._tech;
    }

    @Override
    public String toString()
    {
        return this.getFullyQualifiedName();
    }

    @Override
    public String getSIPSimpleName()
    {
        String name;

        if (isSIP())
            name = getSimpleName();
        else
            name = getFullyQualifiedName();
        return name;
    }

    public boolean isEmpty()
    {
        return this._empty;
    }

}

@@ -4844,16 +4844,51 @@
  + trunk
+.getTrunkAsString()%0A               
  + EndPo
@@ -4904,32 +4904,16 @@
 ELIMITER
-%0A               
  + this.

fix for trunk string