/*
 * Copyright (c) 2006, 2014, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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.
 */
package com.sun.tools.javac.sym;

import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import com.sun.tools.javac.util.Assert;

/**
 * Provide details about profile contents.
 *
 * <p><b>This is NOT part of any supported API.
 * If you write code that depends on this, you do so at your own
 * risk.  This code and its internal interfaces are subject to change
 * or deletion without notice.</b></p>
 */
public abstract class Profiles {
    // for debugging
    public static void main(String[] args) throws IOException {
        Profiles p = Profiles.read(new File(args[0]));
        if (args.length >= 2) {
            Map<Integer,Set<String>> lists = new TreeMap<Integer,Set<String>>();
            for (int i = 1; i <= 4; i++)
                lists.put(i, new TreeSet<String>());

            File rt_jar_lst = new File(args[1]);
            for (String line: Files.readAllLines(rt_jar_lst.toPath(), Charset.defaultCharset())) {
                if (line.endsWith(".class")) {
                    String type = line.substring(0, line.length() - 6);
                    int profile = p.getProfile(type);
                    for (int i = profile; i <= 4; i++)
                        lists.get(i).add(type);
                }
            }

            for (int i = 1; i <= 4; i++) {
                BufferedWriter out = new BufferedWriter(new FileWriter(i + ".txt"));
                try {
                    for (String type: lists.get(i)) {
                        out.write(type);
                        out.newLine();
                    }
                } finally {
                    out.close();
                }
            }
        }
    }

    public static Profiles read(File file) throws IOException {
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
        try {
            Properties p = new Properties();
            p.load(in);
            if (p.containsKey("java/lang/Object"))
                return new SimpleProfiles(p);
            else
                return new MakefileProfiles(p);
        } finally {
            in.close();
        }
    }

    public abstract int getProfileCount();

    public abstract int getProfile(String typeName);

    public abstract Set<String> getPackages(int profile);

    private static class MakefileProfiles extends Profiles {
        static class Package {
            final Package parent;
            final String name;

            Map<String, Package> subpackages = new TreeMap<String, Package>();

            int profile;
            Map<String, Integer> includedTypes = new TreeMap<String,Integer>();
            Map<String, Integer> excludedTypes = new TreeMap<String,Integer>();

            Package(Package parent, String name) {
                this.parent = parent;
                this.name = name;
            }

            int getProfile() {
                return (parent == null) ? profile : Math.max(parent.getProfile(), profile);
            }

            int getProfile(String simpleTypeName) {
                Integer i;
                if ((i = includedTypes.get(simpleTypeName)) != null)
                    return i;
                if ((i = includedTypes.get("*")) != null)
                    return i;
                if ((i = excludedTypes.get(simpleTypeName)) != null)
                    return i + 1;
                if ((i = excludedTypes.get("*")) != null)
                    return i + 1;
                return getProfile();
            }

            String getName() {
                return (parent == null) ? name : (parent.getName() + "/" + name);
            }

            void getPackages(int profile, Set<String> results) {
                int prf = getProfile();
                if (prf != 0 && profile >= prf)
                    results.add(getName());
                for (Package pkg: subpackages.values())
                    pkg.getPackages(profile, results);
            }
        }

        final Map<String, Package> packages = new TreeMap<String, Package>();

        final int maxProfile = 4;  // Three compact profiles plus full JRE

        MakefileProfiles(Properties p) {
            // consider crypto, only if java/lang package exists
            boolean foundJavaLang = false;
            for (int profile = 1; profile <= maxProfile; profile++) {
                String prefix = (profile < maxProfile ? "PROFILE_" + profile : "FULL_JRE");
                String inclPackages = p.getProperty(prefix + "_RTJAR_INCLUDE_PACKAGES");
                if (inclPackages == null)
                    break;
                for (String pkg: inclPackages.substring(1).trim().split("\\s+")) {
                    if (pkg.endsWith("/"))
                        pkg = pkg.substring(0, pkg.length() - 1);
                    if (foundJavaLang == false && pkg.equals("java/lang"))
                        foundJavaLang = true;
                    includePackage(profile, pkg);
                }
                String inclTypes =  p.getProperty(prefix + "_RTJAR_INCLUDE_TYPES");
                if (inclTypes != null) {
                    for (String type: inclTypes.replace("$$", "$").split("\\s+")) {
                        if (type.endsWith(".class"))
                            includeType(profile, type.substring(0, type.length() - 6));
                    }
                }
                String exclTypes =  p.getProperty(prefix + "_RTJAR_EXCLUDE_TYPES");
                if (exclTypes != null) {
                    for (String type: exclTypes.replace("$$", "$").split("\\s+")) {
                        if (type.endsWith(".class"))
                            excludeType(profile, type.substring(0, type.length() - 6));
                    }
                }
            }
            /*
             * A hack to force javax/crypto package into the compact1 profile,
             * because this package exists in jce.jar, and therefore not in
             * ct.sym. Note javax/crypto should exist in a profile along with
             * javax/net/ssl package. Thus, this package is added to compact1,
             * implying that it should exist in all three profiles.
             */
            if (foundJavaLang)
                includePackage(1, "javax/crypto");
        }

        @Override
        public int getProfileCount() {
            return maxProfile;
        }

        @Override
        public int getProfile(String typeName) {
            int sep = typeName.lastIndexOf("/");
            String packageName = typeName.substring(0, sep);
            String simpleName = typeName.substring(sep + 1);

            Package p = getPackage(packageName);
            return p.getProfile(simpleName);
        }

        @Override
        public Set<String> getPackages(int profile) {
            Set<String> results = new TreeSet<String>();
            for (Package p: packages.values())
                p.getPackages(profile, results);
            return results;
        }

        private void includePackage(int profile, String packageName) {
//            System.err.println("include package " + packageName);
            Package p = getPackage(packageName);
            Assert.check(p.profile == 0);
            p.profile = profile;
        }

        private void includeType(int profile, String typeName) {
//            System.err.println("include type " + typeName);
            int sep = typeName.lastIndexOf("/");
            String packageName = typeName.substring(0, sep);
            String simpleName = typeName.substring(sep + 1);

            Package p = getPackage(packageName);
            Assert.check(!p.includedTypes.containsKey(simpleName));
            p.includedTypes.put(simpleName, profile);
        }

        private void excludeType(int profile, String typeName) {
//            System.err.println("exclude type " + typeName);
            int sep = typeName.lastIndexOf("/");
            String packageName = typeName.substring(0, sep);
            String simpleName = typeName.substring(sep + 1);

            Package p = getPackage(packageName);
            Assert.check(!p.excludedTypes.containsKey(simpleName));
            p.excludedTypes.put(simpleName, profile);
        }

        private Package getPackage(String packageName) {
            int sep = packageName.lastIndexOf("/");
            Package parent;
            Map<String, Package> parentSubpackages;
            String simpleName;
            if (sep == -1) {
                parent = null;
                parentSubpackages = packages;
                simpleName = packageName;
            } else {
                parent = getPackage(packageName.substring(0, sep));
                parentSubpackages = parent.subpackages;
                simpleName = packageName.substring(sep + 1);
            }

            Package p = parentSubpackages.get(simpleName);
            if (p == null) {
                parentSubpackages.put(simpleName, p = new Package(parent, simpleName));
            }
            return p;
        }
    }

    private static class SimpleProfiles extends Profiles {
        private final Map<String, Integer> map;
        private final int profileCount;

        SimpleProfiles(Properties p) {
            int max = 0;
            map = new HashMap<String, Integer>();
            for (Map.Entry<Object,Object> e: p.entrySet()) {
                String typeName = (String) e.getKey();
                int profile = Integer.valueOf((String) e.getValue());
                map.put(typeName, profile);
                max = Math.max(max, profile);
            }
            profileCount = max;
        }

        @Override
        public int getProfileCount() {
            return profileCount;
        }

        @Override
        public int getProfile(String typeName) {
            return map.get(typeName);
        }

        @Override
        public Set<String> getPackages(int profile) {
            Set<String> results = new TreeSet<String>();
            for (Map.Entry<String,Integer> e: map.entrySet()) {
                String tn = e.getKey();
                int prf = e.getValue();
                int sep = tn.lastIndexOf("/");
                if (sep > 0 && profile >= prf)
                    results.add(tn);
            }
            return results;
        }
    }
}
