/*
 * 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 com.android.connectivitymanagertest;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.IpAssignment;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiConfiguration.ProxySettings;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.RouteInfo;

import java.io.InputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;


/**
 * Help class to process configurations of access points saved in an XML file.
 * The configurations of an access point is included in tag
 * <accesspoint></accesspoint>. The supported configuration includes: ssid,
 * security, eap, phase2, identity, password, anonymousidentity, cacert, usercert,
 * in which each is included in the corresponding tags. Static IP setting is also supported.
 * Tags that can be used include: ip, gateway, networkprefixlength, dns1, dns2. All access points
 * have to be enclosed in tags of <resources></resources>.
 *
 * The following is a sample configuration file for an access point using EAP-PEAP with MSCHAP2.
 * <resources>
 *   <accesspoint>
 *   <ssid>testnet</ssid>
 *   <security>EAP</security>
 *   <eap>PEAP</eap>
 *   <phase2>MSCHAP2</phase2>
 *   <identity>donut</identity</identity>
 *   <password>abcdefgh</password>
 *   </accesspoint>
 * </resources>
 *
 * Note:ssid and security have to be the first two tags
 *      for static ip setting, tag "ip" should be listed before other fields: dns, gateway,
 *      networkprefixlength.
 */
public class AccessPointParserHelper {
    private static final String TAG = "AccessPointParserHelper";
    static final int NONE = 0;
    static final int WEP = 1;
    static final int PSK = 2;
    static final int EAP = 3;

    List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();

    private int getSecurityType (String security) {
        if (security.equalsIgnoreCase("NONE")) {
            return NONE;
        } else if (security.equalsIgnoreCase("WEP")) {
            return WEP;
        } else if (security.equalsIgnoreCase("PSK")) {
            return PSK;
        } else if (security.equalsIgnoreCase("EAP")) {
            return EAP;
        } else {
            return -1;
        }
    }

    private boolean validateEapValue(String value) {
        if (value.equalsIgnoreCase("PEAP") ||
                value.equalsIgnoreCase("TLS") ||
                value.equalsIgnoreCase("TTLS")) {
            return true;
        } else {
            return false;
        }
    }

    DefaultHandler mHandler = new DefaultHandler() {

        boolean ssid = false;
        boolean security = false;
        boolean password = false;
        boolean ip = false;
        boolean gateway = false;
        boolean networkprefix = false;
        boolean dns1 = false;
        boolean dns2 = false;
        boolean eap = false;
        boolean phase2 = false;
        boolean identity = false;
        boolean anonymousidentity = false;
        boolean cacert = false;
        boolean usercert = false;
        WifiConfiguration config = null;
        int securityType = NONE;
        LinkProperties mLinkProperties = null;
        InetAddress mInetAddr = null;

        @Override
        public void startElement(String uri, String localName, String tagName,
                Attributes attributes) throws SAXException {
            if (tagName.equalsIgnoreCase("accesspoint")) {
                config = new WifiConfiguration();
            }
            if (tagName.equalsIgnoreCase("ssid")) {
                ssid = true;
            }
            if (tagName.equalsIgnoreCase("security")) {
                security = true;
            }
            if (tagName.equalsIgnoreCase("password")) {
                password = true;
            }
            if (tagName.equalsIgnoreCase("eap")) {
                eap = true;
            }
            if (tagName.equalsIgnoreCase("phase2")) {
                phase2 = true;
            }
            if (tagName.equalsIgnoreCase("identity")) {
                identity = true;
            }
            if (tagName.equalsIgnoreCase("anonymousidentity")) {
                anonymousidentity = true;
            }
            if (tagName.equalsIgnoreCase("cacert")) {
                cacert = true;
            }
            if (tagName.equalsIgnoreCase("usercert")) {
                usercert = true;
            }
            if (tagName.equalsIgnoreCase("ip")) {
                mLinkProperties = new LinkProperties();
                ip = true;
            }
            if (tagName.equalsIgnoreCase("gateway")) {
                gateway = true;
            }
            if (tagName.equalsIgnoreCase("networkprefixlength")) {
                networkprefix = true;
            }
            if (tagName.equalsIgnoreCase("dns1")) {
                dns1 = true;
            }
            if (tagName.equalsIgnoreCase("dns2")) {
                dns2 = true;
            }
        }

        @Override
        public void endElement(String uri, String localName, String tagName) throws SAXException {
            if (tagName.equalsIgnoreCase("accesspoint")) {
                if (mLinkProperties != null) {
                    config.ipAssignment = IpAssignment.STATIC;
                    config.linkProperties = mLinkProperties;
                } else {
                    config.ipAssignment = IpAssignment.DHCP;
                }
                config.proxySettings = ProxySettings.NONE;
                networks.add(config);
                mLinkProperties = null;
            }
        }

        @Override
        public void characters(char ch[], int start, int length) throws SAXException {
            if (ssid) {
                config.SSID = new String(ch, start, length);
                ssid = false;
            }
            if (security) {
                String securityStr = (new String(ch, start, length)).toUpperCase();
                securityType = getSecurityType(securityStr);
                switch (securityType) {
                    case NONE:
                        config.allowedKeyManagement.set(KeyMgmt.NONE);
                        break;
                    case WEP:
                        config.allowedKeyManagement.set(KeyMgmt.NONE);
                        config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
                        config.allowedAuthAlgorithms.set(AuthAlgorithm.SHARED);
                        break;
                    case PSK:
                        config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
                        break;
                    case EAP:
                        config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
                        config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
                        // Initialize other fields.
                        config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
                        config.enterpriseConfig.setCaCertificateAlias("");
                        config.enterpriseConfig.setClientCertificateAlias("");
                        config.enterpriseConfig.setIdentity("");
                        config.enterpriseConfig.setAnonymousIdentity("");
                        break;
                    default:
                        throw new SAXException();
                }
                security = false;
            }
            if (password) {
                String passwordStr = new String(ch, start, length);
                int len = passwordStr.length();
                if (len == 0) {
                    throw new SAXException();
                }
                if (securityType == WEP) {
                    if ((len == 10 || len == 26 || len == 58) &&
                            passwordStr.matches("[0-9A-Fa-f]*")) {
                        config.wepKeys[0] = passwordStr;
                    } else {
                        config.wepKeys[0] = '"' + passwordStr + '"';
                    }
                } else if (securityType == PSK) {
                    if (passwordStr.matches("[0-9A-Fa-f]{64}")) {
                        config.preSharedKey = passwordStr;
                    } else {
                        config.preSharedKey = '"' + passwordStr + '"';
                    }
                } else if (securityType == EAP) {
                    config.enterpriseConfig.setPassword(passwordStr);
                } else {
                    throw new SAXException();
                }
                password = false;
            }
            if (eap) {
                String eapValue = new String(ch, start, length);
                if (!validateEapValue(eapValue)) {
                    throw new SAXException();
                }
		if (eapValue.equals("TLS")) {
		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
		} else if (eapValue.equals("TTLS")) {
		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
		} else if (eapValue.equals("PEAP")) {
		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
		}
                eap = false;
            }
            if (phase2) {
                String phase2Value = new String(ch, start, length);
		if (phase2Value.equals("PAP")) {
                    config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
		} else if (phase2Value.equals("MSCHAP")) {
                    config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAP);
		} else if (phase2Value.equals("MSCHAPV2")) {
                    config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
		} else if (phase2Value.equals("GTC")) {
                    config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
		}
                phase2 = false;
            }
            if (identity) {
                String identityValue = new String(ch, start, length);
                config.enterpriseConfig.setIdentity(identityValue);
                identity = false;
            }
            if (anonymousidentity) {
                String anonyId = new String(ch, start, length);
                config.enterpriseConfig.setAnonymousIdentity(anonyId);
                anonymousidentity = false;
            }
            if (cacert) {
                String cacertValue = new String(ch, start, length);
                config.enterpriseConfig.setCaCertificateAlias(cacertValue);
                cacert = false;
            }
            if (usercert) {
                String usercertValue = new String(ch, start, length);
                config.enterpriseConfig.setClientCertificateAlias(usercertValue);
                usercert = false;
            }
            if (ip) {
                try {
                    String ipAddr = new String(ch, start, length);
                    if (!InetAddress.isNumeric(ipAddr)) {
                        throw new SAXException();
                    }
                    mInetAddr = InetAddress.getByName(ipAddr);
                } catch (UnknownHostException e) {
                    throw new SAXException();
                }
                ip = false;
            }
            if (gateway) {
                try {
                    String gwAddr = new String(ch, start, length);
                    if (!InetAddress.isNumeric(gwAddr)) {
                        throw new SAXException();
                    }
                    mLinkProperties.addRoute(new RouteInfo(InetAddress.getByName(gwAddr)));
                } catch (UnknownHostException e) {
                    throw new SAXException();
                }
                gateway = false;
            }
            if (networkprefix) {
                try {
                    int nwPrefixLength = Integer.parseInt(new String(ch, start, length));
                    if ((nwPrefixLength < 0) || (nwPrefixLength > 32)) {
                        throw new SAXException();
                    }
                    mLinkProperties.addLinkAddress(new LinkAddress(mInetAddr, nwPrefixLength));
                } catch (NumberFormatException e) {
                    throw new SAXException();
                }
                networkprefix = false;
            }
            if (dns1) {
                try {
                    String dnsAddr = new String(ch, start, length);
                    if (!InetAddress.isNumeric(dnsAddr)) {
                        throw new SAXException();
                    }
                    mLinkProperties.addDns(InetAddress.getByName(dnsAddr));
                } catch (UnknownHostException e) {
                    throw new SAXException();
                }
                dns1 = false;
            }
            if (dns2) {
                try {
                    String dnsAddr = new String(ch, start, length);
                    if (!InetAddress.isNumeric(dnsAddr)) {
                        throw new SAXException();
                    }
                    mLinkProperties.addDns(InetAddress.getByName(dnsAddr));
                } catch (UnknownHostException e) {
                    throw new SAXException();
                }
                dns2 = false;
            }
        }
    };

    /**
     * Process the InputStream in
     * @param in is the InputStream that can be used for XML parsing
     * @throws Exception
     */
    public AccessPointParserHelper(InputStream in) throws Exception {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();
        saxParser.parse(in, mHandler);
    }

    public List<WifiConfiguration> getNetworkConfigurations() throws Exception {
        return networks;
    }
}
