/*
 * Copyright (C) 2006-2020 Apple Inc. All rights reserved.
 * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "PluginPackage.h"
#include <wtf/HashSet.h>
#include <wtf/Vector.h>
#include <wtf/text/StringHash.h>

namespace WebCore {

    typedef HashSet<RefPtr<PluginPackage>, PluginPackageHash, PluginPackageHashTraits> PluginSet;

    class PluginDatabase {
        WTF_MAKE_NONCOPYABLE(PluginDatabase); WTF_MAKE_FAST_ALLOCATED;
    public:
        PluginDatabase();

        // The first call to installedPlugins creates the plugin database
        // and by default populates it with the plugins installed on the system.
        // For testing purposes, it is possible to not populate the database
        // automatically, as the plugins might affect the DRT results by
        // writing to a.o. stderr.
        static PluginDatabase* installedPlugins(bool populate = true);

        bool refresh();
        void clear();
        Vector<PluginPackage*> plugins() const;
        bool isMIMETypeRegistered(const String& mimeType);
        void addExtraPluginDirectory(const String&);

        static bool isPreferredPluginDirectory(const String& directory);
        static int preferredPluginCompare(const void*, const void*);

        PluginPackage* findPlugin(const URL&, String& mimeType);
        PluginPackage* pluginForMIMEType(const String& mimeType);
        void setPreferredPluginForMIMEType(const String& mimeType, PluginPackage* plugin);

        void setPluginDirectories(const Vector<String>& directories)
        {
            clear();
            m_pluginDirectories = directories;
        }

        bool removeDisabledPluginFile(const String& fileName);
        bool addDisabledPluginFile(const String& fileName);
        static Vector<String> defaultPluginDirectories();
        Vector<String> pluginDirectories() const { return m_pluginDirectories; }

        String MIMETypeForExtension(StringView extension) const;

#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
        static bool isPersistentMetadataCacheEnabled();
        static void setPersistentMetadataCacheEnabled(bool isEnabled);
        static String persistentMetadataCachePath();
        static void setPersistentMetadataCachePath(const String& persistentMetadataCachePath);
#endif

    private:
        void getPluginPathsInDirectories(HashSet<String>&) const;
        void getDeletedPlugins(PluginSet&) const;
        bool fileExistsAndIsNotDisabled(const String&) const;

        // Returns whether the plugin was actually added or not (it won't be added if it's a duplicate of an existing plugin).
        bool add(Ref<PluginPackage>&&);
        void remove(PluginPackage*);
#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
        void loadPersistentMetadataCache();
        void updatePersistentMetadataCache();
#endif

        HashSet<String> m_disabledPluginFiles;
        Vector<String> m_pluginDirectories;
        HashSet<String> m_registeredMIMETypes;
        PluginSet m_plugins;
        HashMap<String, RefPtr<PluginPackage> > m_pluginsByPath;
        HashMap<String, time_t> m_pluginPathsWithTimes;
        HashMap<String, RefPtr<PluginPackage>, ASCIICaseInsensitiveHash> m_preferredPlugins;
#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
        bool m_persistentMetadataCacheIsLoaded { false };
#endif
    };

} // namespace WebCore
