/*
 * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

import static java.lang.System.out;
import java.security.Provider;
import java.security.Security;
import java.security.SecureRandom;
import java.security.Provider.Service;
import java.util.Arrays;
import sun.security.provider.SunEntries;

/**
 * @test
 * @bug 8228613 8246613 8248505
 * @summary Ensure that the default SecureRandom algo used is based
 *     on the registration ordering, and falls to next provider
 *     if none are found
 * @modules java.base/sun.security.provider
 */
public class DefaultAlgo {

    private static final String SR_IMPLCLASS =
            "sun.security.provider.SecureRandom";

    public static void main(String[] args) throws Exception {
        String[] algos = { "A", "B", "C" };
        test3rdParty(algos);
        // reverse the order and re-check
        String[] algosReversed = { "C", "B", "A" };
        test3rdParty(algosReversed);
    }

    private static void test3rdParty(String[] algos) {
        Provider[] provs = {
            new SampleLegacyProvider(algos),
            new SampleServiceProvider(algos),
            new CustomProvider(algos)
        };
        for (Provider p : provs) {
            checkDefault(p, algos);
        }
    }

    // validate the specified SecureRandom obj to be from the specified
    // provider and matches the specified algorithm
    private static void validate(SecureRandom sr, String pName, String algo) {
        if (!sr.getProvider().getName().equals(pName)) {
            throw new RuntimeException("Failed provider check, exp: " +
                    pName + ", got " + sr.getProvider().getName());
        }
        if (!sr.getAlgorithm().equals(algo)) {
            throw new RuntimeException("Failed algo check, exp: " +
                    algo + ", got " + sr.getAlgorithm());
        }
    }

    private static void checkDefault(Provider p, String ... algos) {
        String pName = p.getName();
        out.println(pName + " with " + Arrays.toString(algos));
        int pos = Security.insertProviderAt(p, 1);

        boolean isLegacy = pName.equals("SampleLegacy");
        try {
            if (isLegacy) {
                for (String s : algos) {
                    validate(new SecureRandom(), pName, s);
                    p.remove("SecureRandom." + s);
                    out.println("removed "  + s);
                }
                validate(new SecureRandom(), System.getProperty("test.provider.name", "SUN"),
                        System.getProperty("test.default.secure.random.algorithm.name",
                                SunEntries.DEF_SECURE_RANDOM_ALGO));
            } else {
                validate(new SecureRandom(), pName, algos[0]);
            }
            out.println("=> Test Passed");
        } finally {
            if (pos != -1) {
                Security.removeProvider(pName);
            }
            if (isLegacy) {
                // add back the removed algos
                for (String s : algos) {
                    p.put("SecureRandom." + s, SR_IMPLCLASS);
                }
            }
        }
    }

    private static class SampleLegacyProvider extends Provider {
        SampleLegacyProvider(String[] listOfSupportedRNGs) {
            super("SampleLegacy", "1.0", "test provider using legacy put");
            for (String s : listOfSupportedRNGs) {
                put("SecureRandom." + s, SR_IMPLCLASS);
            }
        }
    }

    private static class SampleServiceProvider extends Provider {
        SampleServiceProvider(String[] listOfSupportedRNGs) {
            super("SampleService", "1.0", "test provider using putService");
            for (String s : listOfSupportedRNGs) {
                putService(new Provider.Service(this, "SecureRandom", s,
                        SR_IMPLCLASS, null, null));
            }
        }
    }

    // custom provider which overrides putService(...)/getService() and uses
    // its own Service impl
    private static class CustomProvider extends Provider {
        private static class CustomService extends Provider.Service {
            CustomService(Provider p, String type, String algo, String cName) {
                super(p, type, algo, cName, null, null);
            }
        }

        CustomProvider(String[] listOfSupportedRNGs) {
            super("Custom", "1.0", "test provider overrides putService with " +
                    " custom service with legacy registration");
            for (String s : listOfSupportedRNGs) {
                putService(new CustomService(this, "SecureRandom", s ,
                        SR_IMPLCLASS));
            }
        }
        @Override
        protected void putService(Provider.Service s) {
            // convert to legacy puts
            put(s.getType() + "." + s.getAlgorithm(), s.getClassName());
            put(s.getType() + ":" + s.getAlgorithm(), s);
        }
        @Override
        public Provider.Service getService(String type, String algo) {
            return (Provider.Service) get(type + ":" + algo);
        }
    }
}
