/*
 * Copyright (C) 2014 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.wifi.passpoint;

import android.net.wifi.WifiConfiguration;
import android.net.wifi.ScanResult;
import android.os.Parcelable;
import android.os.Parcel;
import android.security.Credentials;
import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;


/** @hide */
public class WifiPasspointPolicy implements Parcelable {

    private final static String TAG = "PasspointPolicy";

    /** @hide */
    public static final int HOME_SP = 0;

    /** @hide */
    public static final int ROAMING_PARTNER = 1;

    /** @hide */
    public static final int UNRESTRICTED = 2;

    private String mName;
    private int mCredentialPriority;
    private int mRoamingPriority;
    private String mBssid;
    private String mSsid;
    private WifiPasspointCredential mCredential;
    private int mRestriction;// Permitted values are "HomeSP", "RoamingPartner", or "Unrestricted"
    private boolean mIsHomeSp;

    private final String INT_PRIVATE_KEY = "private_key";
    private final String INT_PHASE2 = "phase2";
    private final String INT_PASSWORD = "password";
    private final String INT_IDENTITY = "identity";
    private final String INT_EAP = "eap";
    private final String INT_CLIENT_CERT = "client_cert";
    private final String INT_CA_CERT = "ca_cert";
    private final String INT_ANONYMOUS_IDENTITY = "anonymous_identity";
    private final String INT_SIM_SLOT = "sim_slot";
    private final String INT_ENTERPRISEFIELD_NAME ="android.net.wifi.WifiConfiguration$EnterpriseField";
    private final String ISO8601DATEFORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    private final String ENTERPRISE_PHASE2_MSCHAPV2 = "auth=MSCHAPV2";
    private final String ENTERPRISE_PHASE2_MSCHAP = "auth=MSCHAP";

    /** @hide */
    public WifiPasspointPolicy(String name, String ssid,
            String bssid, WifiPasspointCredential pc,
            int restriction, boolean ishomesp) {
        mName = name;
        if (pc != null) {
            mCredentialPriority = pc.getPriority();
        }
        //PerProviderSubscription/<X+>/Policy/PreferredRoamingPartnerList/<X+>/Priority
        mRoamingPriority = 128; //default priority value of 128
        mSsid = ssid;
        mCredential = pc;
        mBssid = bssid;
        mRestriction = restriction;
        mIsHomeSp = ishomesp;
    }

    public String getSsid() {
        return mSsid;
    }

    /** @hide */
    public void setBssid(String bssid) {
        mBssid = bssid;
    }

    public String getBssid() {
        return mBssid;
    }

    /** @hide */
    public void setRestriction(int r) {
        mRestriction = r;
    }

    /** @hide */
    public int getRestriction() {
        return mRestriction;
    }

    /** @hide */
    public void setHomeSp(boolean b) {
        mIsHomeSp = b;
    }

    /** @hide */
    public boolean isHomeSp() {
        return mIsHomeSp;
    }

    /** @hide */
    public void setCredential(WifiPasspointCredential newCredential) {
        mCredential = newCredential;
    }

    public WifiPasspointCredential getCredential() {
        // TODO: return a copy
        return mCredential;
    }

    /** @hide */
    public void setCredentialPriority(int priority) {
        mCredentialPriority = priority;
    }

    /** @hide */
    public void setRoamingPriority(int priority) {
        mRoamingPriority = priority;
    }

    public int getCredentialPriority() {
        return mCredentialPriority;
    }

    public int getRoamingPriority() {
        return mRoamingPriority;
    }

    public WifiConfiguration createWifiConfiguration() {
        WifiConfiguration wfg = new WifiConfiguration();
        if (mBssid != null) {
            Log.d(TAG, "create bssid:" + mBssid);
            wfg.BSSID = mBssid;
        }

        if (mSsid != null) {
            Log.d(TAG, "create ssid:" + mSsid);
            wfg.SSID = mSsid;
        }
        //TODO: 1. add pmf configuration
        //      2. add ocsp configuration
        //      3. add eap-sim configuration
        /*Key management*/
        wfg.status = WifiConfiguration.Status.ENABLED;
        wfg.allowedKeyManagement.clear();
        wfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
        wfg.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);

        /*Group Ciphers*/
        wfg.allowedGroupCiphers.clear();
        wfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        wfg.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);

        /*Protocols*/
        wfg.allowedProtocols.clear();
        wfg.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        wfg.allowedProtocols.set(WifiConfiguration.Protocol.WPA);

        Class[] enterpriseFieldArray  = WifiConfiguration.class.getClasses();
        Class<?> enterpriseFieldClass = null;


        for(Class<?> myClass : enterpriseFieldArray) {
            if(myClass.getName().equals(INT_ENTERPRISEFIELD_NAME)) {
                enterpriseFieldClass = myClass;
                break;
            }
        }
        Log.d(TAG, "class chosen " + enterpriseFieldClass.getName() );


        Field anonymousId = null, caCert = null, clientCert = null,
              eap = null, identity = null, password = null,
              phase2 = null, privateKey =  null;

        Field[] fields = WifiConfiguration.class.getFields();


        for (Field tempField : fields) {
            if (tempField.getName().trim().equals(INT_ANONYMOUS_IDENTITY)) {
                anonymousId = tempField;
                Log.d(TAG, "field " + anonymousId.getName() );
            } else if (tempField.getName().trim().equals(INT_CA_CERT)) {
                caCert = tempField;
            } else if (tempField.getName().trim().equals(INT_CLIENT_CERT)) {
                clientCert = tempField;
                Log.d(TAG, "field " + clientCert.getName() );
            } else if (tempField.getName().trim().equals(INT_EAP)) {
                eap = tempField;
                Log.d(TAG, "field " + eap.getName() );
            } else if (tempField.getName().trim().equals(INT_IDENTITY)) {
                identity = tempField;
                Log.d(TAG, "field " + identity.getName() );
            } else if (tempField.getName().trim().equals(INT_PASSWORD)) {
                password = tempField;
                Log.d(TAG, "field " + password.getName() );
            } else if (tempField.getName().trim().equals(INT_PHASE2)) {
                phase2 = tempField;
                Log.d(TAG, "field " + phase2.getName() );

            } else if (tempField.getName().trim().equals(INT_PRIVATE_KEY)) {
                privateKey = tempField;
            }
        }


        Method setValue = null;

        for(Method m: enterpriseFieldClass.getMethods()) {
            if(m.getName().trim().equals("setValue")) {
                Log.d(TAG, "method " + m.getName() );
                setValue = m;
                break;
            }
        }

        try {
            // EAP
            String eapmethod = mCredential.getType();
            Log.d(TAG, "eapmethod:" + eapmethod);
            setValue.invoke(eap.get(wfg), eapmethod);

            // Username, password, EAP Phase 2
            if ("TTLS".equals(eapmethod)) {
                setValue.invoke(phase2.get(wfg), ENTERPRISE_PHASE2_MSCHAPV2);
                setValue.invoke(identity.get(wfg), mCredential.getUserName());
                setValue.invoke(password.get(wfg), mCredential.getPassword());
                setValue.invoke(anonymousId.get(wfg), "anonymous@" + mCredential.getRealm());
            }

            // EAP CA Certificate
            String cacertificate = null;
            String rootCA = mCredential.getCaRootCertPath();
            if (rootCA == null){
                cacertificate = null;
            } else {
                cacertificate = "keystore://" + Credentials.WIFI + "HS20" + Credentials.CA_CERTIFICATE + rootCA;
            }
            Log.d(TAG, "cacertificate:" + cacertificate);
            setValue.invoke(caCert.get(wfg), cacertificate);

            //User certificate
            if ("TLS".equals(eapmethod)) {
                String usercertificate = null;
                String privatekey = null;
                String clientCertPath = mCredential.getClientCertPath();
                if (clientCertPath != null){
                    privatekey = "keystore://" + Credentials.WIFI + "HS20" + Credentials.USER_PRIVATE_KEY + clientCertPath;
                    usercertificate = "keystore://" + Credentials.WIFI + "HS20" + Credentials.USER_CERTIFICATE + clientCertPath;
                }
                Log.d(TAG, "privatekey:" + privatekey);
                Log.d(TAG, "usercertificate:" + usercertificate);
                if (privatekey != null && usercertificate != null) {
                    setValue.invoke(privateKey.get(wfg), privatekey);
                    setValue.invoke(clientCert.get(wfg), usercertificate);
                }
            }
        } catch (Exception e) {
            Log.d(TAG, "createWifiConfiguration err:" + e);
        }

        return wfg;
    }

    /** {@inheritDoc} @hide */
    public int compareTo(WifiPasspointPolicy another) {
        Log.d(TAG, "this:" + this);
        Log.d(TAG, "another:" + another);

        if (another == null) {
            return -1;
        } else if (this.mIsHomeSp == true && another.isHomeSp() == false) {
            //home sp priority is higher then roaming
            Log.d(TAG, "compare HomeSP  first, this is HomeSP, another isn't");
            return -1;
        } else if ((this.mIsHomeSp == true && another.isHomeSp() == true)) {
            Log.d(TAG, "both HomeSP");
            //if both home sp, compare credential priority
            if (this.mCredentialPriority < another.getCredentialPriority()) {
                Log.d(TAG, "this priority is higher");
                return -1;
            } else if (this.mCredentialPriority == another.getCredentialPriority()) {
                Log.d(TAG, "both priorities equal");
                //if priority still the same, compare name(ssid)
                if (this.mName.compareTo(another.mName) != 0) {
                    Log.d(TAG, "compare mName return:" + this.mName.compareTo(another.mName));
                    return this.mName.compareTo(another.mName);
                }
                /**
                 *if name still the same, compare credential
                 *the device may has two more credentials(TLS,SIM..etc)
                 *it can associate to one AP(same ssid). so we should compare by credential
                 */
                if (this.mCredential != null && another.mCredential != null) {
                    if (this.mCredential.compareTo(another.mCredential) != 0) {
                        Log.d(TAG,
                                "compare mCredential return:" + this.mName.compareTo(another.mName));
                        return this.mCredential.compareTo(another.mCredential);
                    }
                }
            } else {
                return 1;
            }
        } else if ((this.mIsHomeSp == false && another.isHomeSp() == false)) {
            Log.d(TAG, "both RoamingSp");
            //if both roaming sp, compare roaming priority(preferredRoamingPartnerList/<X+>/priority)
            if (this.mRoamingPriority < another.getRoamingPriority()) {
                Log.d(TAG, "this priority is higher");
                return -1;
            } else if (this.mRoamingPriority == another.getRoamingPriority()) {//priority equals, compare name
                Log.d(TAG, "both priorities equal");
                //if priority still the same, compare name(ssid)
                if (this.mName.compareTo(another.mName) != 0) {
                    Log.d(TAG, "compare mName return:" + this.mName.compareTo(another.mName));
                    return this.mName.compareTo(another.mName);
                }
                //if name still the same, compare credential
                if (this.mCredential != null && another.mCredential != null) {
                    if (this.mCredential.compareTo(another.mCredential) != 0) {
                        Log.d(TAG,
                                "compare mCredential return:"
                                        + this.mCredential.compareTo(another.mCredential));
                        return this.mCredential.compareTo(another.mCredential);
                    }
                }
            } else {
                return 1;
            }
        }

        Log.d(TAG, "both policies equal");
        return 0;
    }

    @Override
    /** @hide */
    public String toString() {
        return "PasspointPolicy: name=" + mName + " CredentialPriority=" + mCredentialPriority +
                " mRoamingPriority" + mRoamingPriority +
                " ssid=" + mSsid + " restriction=" + mRestriction +
                " ishomesp=" + mIsHomeSp + " Credential=" + mCredential;
    }

    /** Implement the Parcelable interface {@hide} */
    @Override
    public int describeContents() {
        return 0;
    }

    /** Implement the Parcelable interface {@hide} */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // TODO
    }

    /** Implement the Parcelable interface {@hide} */
    public static final Creator<WifiPasspointPolicy> CREATOR =
            new Creator<WifiPasspointPolicy>() {
                @Override
                public WifiPasspointPolicy createFromParcel(Parcel in) {
                    return null;
                }

                @Override
                public WifiPasspointPolicy[] newArray(int size) {
                    return new WifiPasspointPolicy[size];
                }
            };
}
