
package com.criticalblue.reactnative;

import android.util.Log;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.react.bridge.JavaScriptModule;

import okhttp3.CertificatePinner;

public class CertPinnerPackage implements ReactPackage {
    private static final String TAG = "ADInterceptor";

    public CertPinnerPackage() {
        // create custom certificate pinner.
        // needs to use reflection so that class can be generated
        // outside the package library

        CertificatePinner certificatePinner = null;
        List<DomainProperty> domainProperties = new ArrayList<>();
        List<String> selfSignedCerts = new ArrayList<>();
        try {
            Class noparams[] = {};
            Class clazz = Class.forName("com.criticalblue.reactnative.GeneratedCertificatePinner");
            Method method = clazz.getDeclaredMethod("instance", noparams);
            certificatePinner = (CertificatePinner) method.invoke(null);
            Method getProperties = clazz.getDeclaredMethod("getProperties", noparams);
            List<List<Object>> properties = (List<List<Object>>) getProperties.invoke(null);
            for (List<Object> property: properties) {
                DomainProperty domainProperty = new DomainProperty((String) property.get(0),
                        (List<String>) property.get(1), (boolean) property.get(2));
                domainProperties.add(domainProperty);
            }
            Log.i(TAG, "Generated Certficate Pinner in use");

            Method getSelfSignedCerts = clazz.getDeclaredMethod("getSelfSignedCerts", noparams);
            selfSignedCerts = (List<String>) getSelfSignedCerts.invoke(null);
            Log.i(TAG, "Self signed certs: " + selfSignedCerts.size());
        } catch(Exception e){
            Log.e(TAG, "No Generated Certficate Pinner found - " + e.getMessage());
            Log.w(TAG, "CERTIFICATE PINNING NOT BEING USED");
        }

        OkHttpClientProvider.setOkHttpClientFactory(new PinnedClientFactory(certificatePinner, domainProperties, selfSignedCerts));
    }

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        return Arrays.<NativeModule>asList(new CertPinnerModule(reactContext));
    }

    // Deprecated from RN 0.47
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}