/*
 * Copyright (c) 2016, 2018, 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 jdk.jfr.internal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.StringJoiner;

import jdk.jfr.internal.handlers.EventHandler;

final class SettingsManager {

    private static class InternalSetting {

        private final String identifier;
        private Map<String, Set<String>> enabledMap = new LinkedHashMap<>(5);
        private Map<String, Set<String>> allMap = new LinkedHashMap<>(5);
        private boolean enabled;

        /**
         * Settings identifier, for example "com.example.HelloWorld" or "56"
         * (id of event)
         *
         * @param settingsId
         */
        public InternalSetting(String settingsId) {
            this.identifier = settingsId;
        }

        public Set<String> getValues(String key) {
            if (enabled) {
                return enabledMap.get(key);
            } else {
                return allMap.get(key);
            }
        }

        public void add(String attribute, String value) {
            if ("enabled".equals(attribute) && "true".equals(value)) {
                enabled = true;
                allMap = null; // no need to keep these around
            }
            addToMap(enabledMap, attribute, value);
            if (allMap != null) {
                addToMap(allMap, attribute, value);
            }
        }

        private void addToMap(Map<String, Set<String>> map, String attribute, String value) {
            Set<String> values = map.get(attribute);
            if (values == null) {
                values = new HashSet<String>(5);
                map.put(attribute, values);
            }
            values.add(value);

        }

        public String getSettingsId() {
            return identifier;
        }

        public void add(InternalSetting enabled) {
            for (Map.Entry<String, Set<String>> entry : enabled.enabledMap.entrySet()) {
                for (String value : entry.getValue()) {
                    add(entry.getKey(), value);
                }
            }
        }

        public boolean isEnabled() {
            return enabled;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append(identifier);
            sb.append(": ");
            sb.append(enabledMap.toString());
            return sb.toString();
        }

        public void finish() {
            if (!enabled) {
                // settings from disabled
                // events should not impact results, but
                // we can't clear enabledMap since enabled=false
                // needs be there, so events that are enabled
                // by default are turned off
                Map<String, Set<String>> disabledMap = new HashMap<>(2);
                Set<String> values = new HashSet<>(2);
                values.add("false");
                disabledMap.put("enabled", values);
                enabledMap = disabledMap;
            }
        }
    }

   private Map<String, InternalSetting> availableSettings = new LinkedHashMap<>();

    void setSettings(List<Map<String, String>> activeSettings) {
        // store settings so they are available if a new event class is loaded
        availableSettings = createSettingsMap(activeSettings);
        List<EventControl> eventControls = MetadataRepository.getInstance().getEventControls();
        if (!JVM.getJVM().isRecording()) {
            for (EventControl ec : eventControls) {
                ec.disable();
            }
        } else {
            if (Logger.shouldLog(LogTag.JFR_SETTING, LogLevel.INFO)) {
                Collections.sort(eventControls, (x,y) -> x.getEventType().getName().compareTo(y.getEventType().getName()));
            }
            for (EventControl ec : eventControls) {
                setEventControl(ec);
            }
        }
        if (JVM.getJVM().getAllowedToDoEventRetransforms()) {
            updateRetransform(JVM.getJVM().getAllEventClasses());
        }
    }

    public void updateRetransform(List<Class<? extends jdk.internal.event.Event>> eventClasses) {
        List<Class<?>> classes = new ArrayList<>();
        for(Class<? extends jdk.internal.event.Event> eventClass: eventClasses) {
            EventHandler eh = Utils.getHandler(eventClass);
            if (eh != null ) {
                PlatformEventType eventType = eh.getPlatformEventType();
                if (eventType.isMarkedForInstrumentation()) {
                    classes.add(eventClass);
                    eventType.markForInstrumentation(false);
                    // A bit premature to set it here, but hard to check
                    // after call to retransformClasses.
                    eventType.setInstrumented();
                }
            }
        }
        if (!classes.isEmpty()) {
            JVM.getJVM().retransformClasses(classes.toArray(new Class<?>[0]));
        }
    }

    private Map<String, InternalSetting> createSettingsMap(List<Map<String,String>> activeSettings) {
        Map<String, InternalSetting> map = new LinkedHashMap<>(activeSettings.size());
        for (Map<String, String> rec : activeSettings) {
            for (InternalSetting internal : makeInternalSettings(rec)) {
                InternalSetting is = map.get(internal.getSettingsId());
                if (is == null) {
                    map.put(internal.getSettingsId(), internal);
                } else {
                    is.add(internal);
                }
            }
        }
        return map;
    }

    private Collection<InternalSetting> makeInternalSettings(Map<String, String> rec) {
        Map<String, InternalSetting> internals = new LinkedHashMap<>();
        for (Map.Entry<String, String> entry : rec.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            int index = key.indexOf("#");
            if (index > 1 && index < key.length() - 2) {
                String eventName = key.substring(0, index);
                eventName = Utils.upgradeLegacyJDKEvent(eventName);
                InternalSetting s = internals.get(eventName);
                String settingName = key.substring(index + 1).trim();
                if (s == null) {
                    s = new InternalSetting(eventName);
                    internals.put(eventName, s);
                }
                s.add(settingName, value);
            }
        }
      for (InternalSetting s : internals.values()) {
         s.finish();
      }

      return internals.values();
    }

    void setEventControl(EventControl ec) {
        InternalSetting is = getInternalSetting(ec);
        Logger.log(LogTag.JFR_SETTING, LogLevel.INFO, "Applied settings for " + ec.getEventType().getLogName() + " {");
        for (Entry<String, Control> entry : ec.getEntries()) {
            Set<String> values = null;
            String settingName = entry.getKey();
            if (is != null) {
                values = is.getValues(settingName);
            }
            Control control = entry.getValue();
            if (values != null) {
                control.apply(values);
                String after = control.getLastValue();
                if (Logger.shouldLog(LogTag.JFR_SETTING, LogLevel.INFO)) {
                    if (Utils.isSettingVisible(control, ec.getEventType().hasEventHook())) {
                        if (values.size() > 1) {
                            StringJoiner sj = new StringJoiner(", ", "{", "}");
                            for (String s : values) {
                                sj.add("\"" + s + "\"");
                            }
                            String message = "  " + settingName + "= " + sj.toString() + " => \"" + after + "\"";
                            Logger.log(LogTag.JFR_SETTING, LogLevel.INFO, message);
                        } else {
                            String message = "  " + settingName + "=\"" + control.getLastValue() + "\"";
                            Logger.log(LogTag.JFR_SETTING, LogLevel.INFO, message);
                        }
                    }
                }
            } else {
                control.setDefault();
                if (Logger.shouldLog(LogTag.JFR_SETTING, LogLevel.INFO)) {
                    String message = "  " + settingName + "=\"" + control.getLastValue() + "\"";
                    Logger.log(LogTag.JFR_SETTING, LogLevel.INFO, message);
                }
            }
        }
        ec.writeActiveSettingEvent();
        Logger.log(LogTag.JFR_SETTING, LogLevel.INFO, "}");
    }

    private InternalSetting getInternalSetting(EventControl ec) {
        String name = ec.getEventType().getName();
        InternalSetting nameBased = availableSettings.get(name);
        InternalSetting idBased = availableSettings.get(ec.getSettingsId());

        if (nameBased == null && idBased == null) {
            return null;
        }
        if (idBased == null) {
            return nameBased;
        }
        if (nameBased == null) {
            return idBased;
        }
        InternalSetting mixed = new InternalSetting(nameBased.getSettingsId());
        mixed.add(nameBased);
        mixed.add(idBased);
        return mixed;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (InternalSetting enabled : availableSettings.values()) {
            sb.append(enabled.toString());
            sb.append("\n");
        }
        return sb.toString();
    }

    boolean isEnabled(String eventName) {
        InternalSetting is = availableSettings.get(eventName);
        if (is == null) {
            return false;
        }
        return is.isEnabled();
    }
}
