/*
 * Copyright (C) 2014 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 android.service.voice;

import android.Manifest;
import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

/** @hide */
public class VoiceInteractionServiceInfo {
    static final String TAG = "VoiceInteractionServiceInfo";

    private String mParseError;

    private ServiceInfo mServiceInfo;
    private String mSessionService;
    private String mRecognitionService;
    private String mSettingsActivity;
    private boolean mSupportsAssist;
    private boolean mSupportsLaunchFromKeyguard;
    private boolean mSupportsLocalInteraction;

    public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp)
            throws PackageManager.NameNotFoundException {
        this(pm, pm.getServiceInfo(comp, PackageManager.GET_META_DATA));
    }

    public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp, int userHandle)
            throws PackageManager.NameNotFoundException {
        this(pm, getServiceInfoOrThrow(comp, userHandle));
    }

    static ServiceInfo getServiceInfoOrThrow(ComponentName comp, int userHandle)
            throws PackageManager.NameNotFoundException {
        try {
            ServiceInfo si = AppGlobals.getPackageManager().getServiceInfo(comp,
                    PackageManager.GET_META_DATA
                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                            | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                    userHandle);
            if (si != null) {
                return si;
            }
        } catch (RemoteException e) {
        }
        throw new PackageManager.NameNotFoundException(comp.toString());
    }

    public VoiceInteractionServiceInfo(PackageManager pm, ServiceInfo si) {
        if (si == null) {
            mParseError = "Service not available";
            return;
        }
        if (!Manifest.permission.BIND_VOICE_INTERACTION.equals(si.permission)) {
            mParseError = "Service does not require permission "
                    + Manifest.permission.BIND_VOICE_INTERACTION;
            return;
        }

        XmlResourceParser parser = null;
        try {
            parser = si.loadXmlMetaData(pm, VoiceInteractionService.SERVICE_META_DATA);
            if (parser == null) {
                mParseError = "No " + VoiceInteractionService.SERVICE_META_DATA
                        + " meta-data for " + si.packageName;
                return;
            }

            Resources res = pm.getResourcesForApplication(si.applicationInfo);

            AttributeSet attrs = Xml.asAttributeSet(parser);

            int type;
            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
                    && type != XmlPullParser.START_TAG) {
            }

            String nodeName = parser.getName();
            if (!"voice-interaction-service".equals(nodeName)) {
                mParseError = "Meta-data does not start with voice-interaction-service tag";
                return;
            }

            TypedArray array = res.obtainAttributes(attrs,
                    com.android.internal.R.styleable.VoiceInteractionService);
            mSessionService = array.getString(
                    com.android.internal.R.styleable.VoiceInteractionService_sessionService);
            mRecognitionService = array.getString(
                    com.android.internal.R.styleable.VoiceInteractionService_recognitionService);
            mSettingsActivity = array.getString(
                    com.android.internal.R.styleable.VoiceInteractionService_settingsActivity);
            mSupportsAssist = array.getBoolean(
                    com.android.internal.R.styleable.VoiceInteractionService_supportsAssist,
                    false);
            mSupportsLaunchFromKeyguard = array.getBoolean(com.android.internal.
                    R.styleable.VoiceInteractionService_supportsLaunchVoiceAssistFromKeyguard,
                    false);
            mSupportsLocalInteraction = array.getBoolean(com.android.internal.
                    R.styleable.VoiceInteractionService_supportsLocalInteraction, false);
            array.recycle();
            if (mSessionService == null) {
                mParseError = "No sessionService specified";
                return;
            }
            if (mRecognitionService == null) {
                mParseError = "No recognitionService specified";
                return;
            }
        } catch (XmlPullParserException e) {
            mParseError = "Error parsing voice interation service meta-data: " + e;
            Log.w(TAG, "error parsing voice interaction service meta-data", e);
            return;
        } catch (IOException e) {
            mParseError = "Error parsing voice interation service meta-data: " + e;
            Log.w(TAG, "error parsing voice interaction service meta-data", e);
            return;
        } catch (PackageManager.NameNotFoundException e) {
            mParseError = "Error parsing voice interation service meta-data: " + e;
            Log.w(TAG, "error parsing voice interaction service meta-data", e);
            return;
        } finally {
            if (parser != null) parser.close();
        }
        mServiceInfo = si;
    }

    public String getParseError() {
        return mParseError;
    }

    public ServiceInfo getServiceInfo() {
        return mServiceInfo;
    }

    public String getSessionService() {
        return mSessionService;
    }

    public String getRecognitionService() {
        return mRecognitionService;
    }

    public String getSettingsActivity() {
        return mSettingsActivity;
    }

    public boolean getSupportsAssist() {
        return mSupportsAssist;
    }

    public boolean getSupportsLaunchFromKeyguard() {
        return mSupportsLaunchFromKeyguard;
    }

    public boolean getSupportsLocalInteraction() {
        return mSupportsLocalInteraction;
    }
}
