/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.printservice.recommendation;

import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.StringRes;
import com.android.internal.util.Preconditions;

/**
 * Wrapper for a {@link PrintServicePlugin}, isolating issues with the plugin as good as possible
 * from the {@link RecommendationServiceImpl service}.
 */
class RemotePrintServicePlugin implements PrintServicePlugin.PrinterDiscoveryCallback {
    /** Lock for this object */
    private final Object mLock = new Object();

    /** The name of the print service. */
    public final @StringRes int name;

    /** If the print service if for more than a single vendor */
    public final boolean recommendsMultiVendorService;

    /** The package name of the full print service */
    public final @NonNull CharSequence packageName;

    /** Wrapped plugin */
    private final @NonNull PrintServicePlugin mPlugin;

    /** The number of printers discovered by the plugin */
    private @IntRange(from = 0) int mNumPrinters;

    /** If the plugin is started by not yet stopped */
    private boolean isRunning;

    /** Listener for changes to {@link #mNumPrinters}. */
    private @NonNull OnChangedListener mListener;

    /**
     * Create a new remote for a {@link PrintServicePlugin plugin}.
     *
     * @param plugin                       The plugin to be wrapped
     * @param listener                     The listener to be notified about changes in this plugin
     * @param recommendsMultiVendorService If the plugin detects printers of more than a single
     *                                     vendor
     *
     * @throws PluginException If the plugin has issues while caching basic stub properties
     */
    public RemotePrintServicePlugin(@NonNull PrintServicePlugin plugin,
            @NonNull OnChangedListener listener, boolean recommendsMultiVendorService)
            throws PluginException {
        mListener = listener;
        mPlugin = plugin;
        this.recommendsMultiVendorService = recommendsMultiVendorService;

        // We handle any throwable to isolate our self from bugs in the plugin code.
        // Cache simple properties to avoid having to deal with exceptions later in the code.
        try {
            name = Preconditions.checkArgumentPositive(mPlugin.getName(), "name");
            packageName = Preconditions.checkStringNotEmpty(mPlugin.getPackageName(),
                    "packageName");
        } catch (Throwable e) {
            throw new PluginException(mPlugin, "Cannot cache simple properties ", e);
        }

        isRunning = false;
    }

    /**
     * Start the plugin. From now on there might be callbacks to the registered listener.
     */
    public void start()
            throws PluginException {
        // We handle any throwable to isolate our self from bugs in the stub code
        try {
            synchronized (mLock) {
                isRunning = true;
                mPlugin.start(this);
            }
        } catch (Throwable e) {
            throw new PluginException(mPlugin, "Cannot start", e);
        }
    }

    /**
     * Stop the plugin. From this call on there will not be any more callbacks.
     */
    public void stop() throws PluginException {
        // We handle any throwable to isolate our self from bugs in the stub code
        try {
            synchronized (mLock) {
                mPlugin.stop();
                isRunning = false;
            }
        } catch (Throwable e) {
            throw new PluginException(mPlugin, "Cannot stop", e);
        }
    }

    /**
     * Get the current number of printers reported by the stub.
     *
     * @return The number of printers reported by the stub.
     */
    public @IntRange(from = 0) int getNumPrinters() {
        return mNumPrinters;
    }

    @Override
    public void onChanged(@IntRange(from = 0) int numDiscoveredPrinters) {
        synchronized (mLock) {
            Preconditions.checkState(isRunning);

            mNumPrinters = Preconditions.checkArgumentNonnegative(numDiscoveredPrinters,
                    "numDiscoveredPrinters");

            if (mNumPrinters > 0) {
                mListener.onChanged();
            }
        }
    }

    /**
     * Listener to listen for changes to {@link #getNumPrinters}
     */
    public interface OnChangedListener {
        void onChanged();
    }

    /**
     * Exception thrown if the stub has any issues.
     */
    public class PluginException extends Exception {
        private PluginException(PrintServicePlugin plugin, String message, Throwable e) {
            super(plugin + ": " + message, e);
        }
    }
}
