/*
 * Copyright 2019 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.security.identity;

import android.annotation.NonNull;
import android.content.Context;
import android.security.GateKeeper;

import java.io.ByteArrayInputStream;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.LinkedList;

class CredstoreWritableIdentityCredential extends WritableIdentityCredential {

    private static final String TAG = "CredstoreWritableIdentityCredential";

    private String mDocType;
    private String mCredentialName;
    private Context mContext;
    private IWritableCredential mBinder;

    CredstoreWritableIdentityCredential(Context context,
            @NonNull String credentialName,
            @NonNull String docType,
            IWritableCredential binder) {
        mContext = context;
        mDocType = docType;
        mCredentialName = credentialName;
        mBinder = binder;
    }

    @NonNull @Override
    public Collection<X509Certificate> getCredentialKeyCertificateChain(@NonNull byte[] challenge) {
        try {
            byte[] certsBlob = mBinder.getCredentialKeyCertificateChain(challenge);
            ByteArrayInputStream bais = new ByteArrayInputStream(certsBlob);

            Collection<? extends Certificate> certs = null;
            try {
                CertificateFactory factory = CertificateFactory.getInstance("X.509");
                certs = factory.generateCertificates(bais);
            } catch (CertificateException e) {
                throw new RuntimeException("Error decoding certificates", e);
            }

            LinkedList<X509Certificate> x509Certs = new LinkedList<>();
            for (Certificate cert : certs) {
                x509Certs.add((X509Certificate) cert);
            }
            return x509Certs;
        } catch (android.os.RemoteException e) {
            throw new RuntimeException("Unexpected RemoteException ", e);
        } catch (android.os.ServiceSpecificException e) {
            throw new RuntimeException("Unexpected ServiceSpecificException with code "
                    + e.errorCode, e);
        }
    }

    @NonNull @Override
    public byte[] personalize(@NonNull PersonalizationData personalizationData) {

        Collection<AccessControlProfile> accessControlProfiles =
                personalizationData.getAccessControlProfiles();

        AccessControlProfileParcel[] acpParcels =
                new AccessControlProfileParcel[accessControlProfiles.size()];
        boolean usingUserAuthentication = false;
        int n = 0;
        for (AccessControlProfile profile : accessControlProfiles) {
            acpParcels[n] = new AccessControlProfileParcel();
            acpParcels[n].id = profile.getAccessControlProfileId().getId();
            X509Certificate cert = profile.getReaderCertificate();
            if (cert != null) {
                try {
                    acpParcels[n].readerCertificate = cert.getEncoded();
                } catch (CertificateException e) {
                    throw new RuntimeException("Error encoding reader certificate", e);
                }
            } else {
                acpParcels[n].readerCertificate = new byte[0];
            }
            acpParcels[n].userAuthenticationRequired = profile.isUserAuthenticationRequired();
            acpParcels[n].userAuthenticationTimeoutMillis = profile.getUserAuthenticationTimeout();
            if (profile.isUserAuthenticationRequired()) {
                usingUserAuthentication = true;
            }
            n++;
        }

        Collection<String> namespaces = personalizationData.getNamespaces();

        EntryNamespaceParcel[] ensParcels  = new EntryNamespaceParcel[namespaces.size()];
        n = 0;
        for (String namespaceName : namespaces) {
            PersonalizationData.NamespaceData nsd =
                    personalizationData.getNamespaceData(namespaceName);

            ensParcels[n] = new EntryNamespaceParcel();
            ensParcels[n].namespaceName = namespaceName;

            Collection<String> entryNames = nsd.getEntryNames();
            EntryParcel[] eParcels = new EntryParcel[entryNames.size()];
            int m = 0;
            for (String entryName : entryNames) {
                eParcels[m] = new EntryParcel();
                eParcels[m].name = entryName;
                eParcels[m].value = nsd.getEntryValue(entryName);
                Collection<AccessControlProfileId> acpIds =
                        nsd.getAccessControlProfileIds(entryName);
                eParcels[m].accessControlProfileIds = new int[acpIds.size()];
                int o = 0;
                for (AccessControlProfileId acpId : acpIds) {
                    eParcels[m].accessControlProfileIds[o++] = acpId.getId();
                }
                m++;
            }
            ensParcels[n].entries = eParcels;
            n++;
        }

        // Note: The value 0 is used to convey that no user-authentication is needed for this
        // credential. This is to allow creating credentials w/o user authentication on devices
        // where Secure lock screen is not enabled.
        long secureUserId = 0;
        if (usingUserAuthentication) {
            secureUserId = getRootSid();
        }
        try {
            byte[] personalizationReceipt = mBinder.personalize(acpParcels, ensParcels,
                    secureUserId);
            return personalizationReceipt;
        } catch (android.os.RemoteException e) {
            throw new RuntimeException("Unexpected RemoteException ", e);
        } catch (android.os.ServiceSpecificException e) {
            throw new RuntimeException("Unexpected ServiceSpecificException with code "
                    + e.errorCode, e);
        }
    }

    private static long getRootSid() {
        long rootSid = GateKeeper.getSecureUserId();
        if (rootSid == 0) {
            throw new IllegalStateException("Secure lock screen must be enabled"
                    + " to create credentials requiring user authentication");
        }
        return rootSid;
    }


}
