/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with 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.
 */

package android.net.sip;

import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;

import java.io.ObjectStreamException;
import java.io.Serializable;
import java.text.ParseException;
import javax.sip.InvalidArgumentException;
import javax.sip.ListeningPoint;
import javax.sip.PeerUnavailableException;
import javax.sip.SipFactory;
import javax.sip.address.Address;
import javax.sip.address.AddressFactory;
import javax.sip.address.SipURI;
import javax.sip.address.URI;

/**
 * Defines a SIP profile, including a SIP account, domain and server information.
 * <p>You can create a {@link SipProfile} using {@link
 * SipProfile.Builder}. You can also retrieve one from a {@link SipSession}, using {@link
 * SipSession#getLocalProfile} and {@link SipSession#getPeerProfile}.</p>
 *
 * <div class="special reference">
 * <h3>Developer Guides</h3>
 * <p>For more information about using SIP, read the
 * <a href="{@docRoot}guide/topics/network/sip.html">Session Initiation Protocol</a>
 * developer guide.</p>
 * </div>
 */
public class SipProfile implements Parcelable, Serializable, Cloneable {
    private static final long serialVersionUID = 1L;
    private static final int DEFAULT_PORT = 5060;
    private static final String TCP = "TCP";
    private static final String UDP = "UDP";
    private Address mAddress;
    private String mProxyAddress;
    private String mPassword;
    private String mDomain;
    private String mProtocol = UDP;
    private String mProfileName;
    private String mAuthUserName;
    private int mPort = DEFAULT_PORT;
    private boolean mSendKeepAlive = false;
    private boolean mAutoRegistration = true;
    private transient int mCallingUid = 0;

    public static final Parcelable.Creator<SipProfile> CREATOR =
            new Parcelable.Creator<SipProfile>() {
                public SipProfile createFromParcel(Parcel in) {
                    return new SipProfile(in);
                }

                public SipProfile[] newArray(int size) {
                    return new SipProfile[size];
                }
            };

    /**
     * Helper class for creating a {@link SipProfile}.
     */
    public static class Builder {
        private AddressFactory mAddressFactory;
        private SipProfile mProfile = new SipProfile();
        private SipURI mUri;
        private String mDisplayName;
        private String mProxyAddress;

        {
            try {
                mAddressFactory =
                        SipFactory.getInstance().createAddressFactory();
            } catch (PeerUnavailableException e) {
                throw new RuntimeException(e);
            }
        }

        /**
         * Creates a builder based on the given profile.
         */
        public Builder(SipProfile profile) {
            if (profile == null) throw new NullPointerException();
            try {
                mProfile = (SipProfile) profile.clone();
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException("should not occur", e);
            }
            mProfile.mAddress = null;
            mUri = profile.getUri();
            mUri.setUserPassword(profile.getPassword());
            mDisplayName = profile.getDisplayName();
            mProxyAddress = profile.getProxyAddress();
            mProfile.mPort = profile.getPort();
        }

        /**
         * Constructor.
         *
         * @param uriString the URI string as "sip:<user_name>@<domain>"
         * @throws ParseException if the string is not a valid URI
         */
        public Builder(String uriString) throws ParseException {
            if (uriString == null) {
                throw new NullPointerException("uriString cannot be null");
            }
            URI uri = mAddressFactory.createURI(fix(uriString));
            if (uri instanceof SipURI) {
                mUri = (SipURI) uri;
            } else {
                throw new ParseException(uriString + " is not a SIP URI", 0);
            }
            mProfile.mDomain = mUri.getHost();
        }

        /**
         * Constructor.
         *
         * @param username username of the SIP account
         * @param serverDomain the SIP server domain; if the network address
         *      is different from the domain, use {@link #setOutboundProxy} to
         *      set server address
         * @throws ParseException if the parameters are not valid
         */
        public Builder(String username, String serverDomain)
                throws ParseException {
            if ((username == null) || (serverDomain == null)) {
                throw new NullPointerException(
                        "username and serverDomain cannot be null");
            }
            mUri = mAddressFactory.createSipURI(username, serverDomain);
            mProfile.mDomain = serverDomain;
        }

        private String fix(String uriString) {
            return (uriString.trim().toLowerCase().startsWith("sip:")
                    ? uriString
                    : "sip:" + uriString);
        }

        /**
         * Sets the username used for authentication.
         *
         * @param name authentication username of the profile
         * @return this builder object
         */
        public Builder setAuthUserName(String name) {
            mProfile.mAuthUserName = name;
            return this;
        }

        /**
         * Sets the name of the profile. This name is given by user.
         *
         * @param name name of the profile
         * @return this builder object
         */
        public Builder setProfileName(String name) {
            mProfile.mProfileName = name;
            return this;
        }

        /**
         * Sets the password of the SIP account
         *
         * @param password password of the SIP account
         * @return this builder object
         */
        public Builder setPassword(String password) {
            mUri.setUserPassword(password);
            return this;
        }

        /**
         * Sets the port number of the server. By default, it is 5060.
         *
         * @param port port number of the server
         * @return this builder object
         * @throws IllegalArgumentException if the port number is out of range
         */
        public Builder setPort(int port) throws IllegalArgumentException {
            if ((port > 65535) || (port < 1000)) {
                throw new IllegalArgumentException("incorrect port arugment: " + port);
            }
            mProfile.mPort = port;
            return this;
        }

        /**
         * Sets the protocol used to connect to the SIP server. Currently,
         * only "UDP" and "TCP" are supported.
         *
         * @param protocol the protocol string
         * @return this builder object
         * @throws IllegalArgumentException if the protocol is not recognized
         */
        public Builder setProtocol(String protocol)
                throws IllegalArgumentException {
            if (protocol == null) {
                throw new NullPointerException("protocol cannot be null");
            }
            protocol = protocol.toUpperCase();
            if (!protocol.equals(UDP) && !protocol.equals(TCP)) {
                throw new IllegalArgumentException(
                        "unsupported protocol: " + protocol);
            }
            mProfile.mProtocol = protocol;
            return this;
        }

        /**
         * Sets the outbound proxy of the SIP server.
         *
         * @param outboundProxy the network address of the outbound proxy
         * @return this builder object
         */
        public Builder setOutboundProxy(String outboundProxy) {
            mProxyAddress = outboundProxy;
            return this;
        }

        /**
         * Sets the display name of the user.
         *
         * @param displayName display name of the user
         * @return this builder object
         */
        public Builder setDisplayName(String displayName) {
            mDisplayName = displayName;
            return this;
        }

        /**
         * Sets the send keep-alive flag.
         *
         * @param flag true if sending keep-alive message is required,
         *      false otherwise
         * @return this builder object
         */
        public Builder setSendKeepAlive(boolean flag) {
            mProfile.mSendKeepAlive = flag;
            return this;
        }


        /**
         * Sets the auto. registration flag.
         *
         * @param flag true if the profile will be registered automatically,
         *      false otherwise
         * @return this builder object
         */
        public Builder setAutoRegistration(boolean flag) {
            mProfile.mAutoRegistration = flag;
            return this;
        }

        /**
         * Builds and returns the SIP profile object.
         *
         * @return the profile object created
         */
        public SipProfile build() {
            // remove password from URI
            mProfile.mPassword = mUri.getUserPassword();
            mUri.setUserPassword(null);
            try {
                if (!TextUtils.isEmpty(mProxyAddress)) {
                    SipURI uri = (SipURI)
                            mAddressFactory.createURI(fix(mProxyAddress));
                    mProfile.mProxyAddress = uri.getHost();
                } else {
                    if (!mProfile.mProtocol.equals(UDP)) {
                        mUri.setTransportParam(mProfile.mProtocol);
                    }
                    if (mProfile.mPort != DEFAULT_PORT) {
                        mUri.setPort(mProfile.mPort);
                    }
                }
                mProfile.mAddress = mAddressFactory.createAddress(
                        mDisplayName, mUri);
            } catch (InvalidArgumentException e) {
                throw new RuntimeException(e);
            } catch (ParseException e) {
                // must not occur
                throw new RuntimeException(e);
            }
            return mProfile;
        }
    }

    private SipProfile() {
    }

    private SipProfile(Parcel in) {
        mAddress = (Address) in.readSerializable();
        mProxyAddress = in.readString();
        mPassword = in.readString();
        mDomain = in.readString();
        mProtocol = in.readString();
        mProfileName = in.readString();
        mSendKeepAlive = (in.readInt() == 0) ? false : true;
        mAutoRegistration = (in.readInt() == 0) ? false : true;
        mCallingUid = in.readInt();
        mPort = in.readInt();
        mAuthUserName = in.readString();
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeSerializable(mAddress);
        out.writeString(mProxyAddress);
        out.writeString(mPassword);
        out.writeString(mDomain);
        out.writeString(mProtocol);
        out.writeString(mProfileName);
        out.writeInt(mSendKeepAlive ? 1 : 0);
        out.writeInt(mAutoRegistration ? 1 : 0);
        out.writeInt(mCallingUid);
        out.writeInt(mPort);
        out.writeString(mAuthUserName);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * Gets the SIP URI of this profile.
     *
     * @return the SIP URI of this profile
     * @hide
     */
    public SipURI getUri() {
        return (SipURI) mAddress.getURI();
    }

    /**
     * Gets the SIP URI string of this profile.
     *
     * @return the SIP URI string of this profile
     */
    public String getUriString() {
        // We need to return the sip uri domain instead of
        // the SIP URI with transport, port information if
        // the outbound proxy address exists.
        if (!TextUtils.isEmpty(mProxyAddress)) {
            return "sip:" + getUserName() + "@" + mDomain;
        }
        return getUri().toString();
    }

    /**
     * Gets the SIP address of this profile.
     *
     * @return the SIP address of this profile
     * @hide
     */
    public Address getSipAddress() {
        return mAddress;
    }

    /**
     * Gets the display name of the user.
     *
     * @return the display name of the user
     */
    public String getDisplayName() {
        return mAddress.getDisplayName();
    }

    /**
     * Gets the username.
     *
     * @return the username
     */
    public String getUserName() {
        return getUri().getUser();
    }

    /**
     * Gets the username for authentication. If it is null, then the username
     * is used in authentication instead.
     *
     * @return the authentication username
     * @see #getUserName
     */
    public String getAuthUserName() {
        return mAuthUserName;
    }

    /**
     * Gets the password.
     *
     * @return the password
     */
    public String getPassword() {
        return mPassword;
    }

    /**
     * Gets the SIP domain.
     *
     * @return the SIP domain
     */
    public String getSipDomain() {
        return mDomain;
    }

    /**
     * Gets the port number of the SIP server.
     *
     * @return the port number of the SIP server
     */
    public int getPort() {
        return mPort;
    }

    /**
     * Gets the protocol used to connect to the server.
     *
     * @return the protocol
     */
    public String getProtocol() {
        return mProtocol;
    }

    /**
     * Gets the network address of the server outbound proxy.
     *
     * @return the network address of the server outbound proxy
     */
    public String getProxyAddress() {
        return mProxyAddress;
    }

    /**
     * Gets the (user-defined) name of the profile.
     *
     * @return name of the profile
     */
    public String getProfileName() {
        return mProfileName;
    }

    /**
     * Gets the flag of 'Sending keep-alive'.
     *
     * @return the flag of sending SIP keep-alive messages.
     */
    public boolean getSendKeepAlive() {
        return mSendKeepAlive;
    }

    /**
     * Gets the flag of 'Auto Registration'.
     *
     * @return the flag of registering the profile automatically.
     */
    public boolean getAutoRegistration() {
        return mAutoRegistration;
    }

    /**
     * Sets the calling process's Uid in the sip service.
     */
    public void setCallingUid(int uid) {
        mCallingUid = uid;
    }

    /**
     * Gets the calling process's Uid in the sip settings.
     *
     * @return the calling process's Uid in the sip settings.
     * @hide
     */
    @SystemApi
    public int getCallingUid() {
        return mCallingUid;
    }

    private Object readResolve() throws ObjectStreamException {
        // For compatibility.
        if (mPort == 0) mPort = DEFAULT_PORT;
        return this;
    }
}
