/*
 * 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 android.hardware.location;


import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * @hide
 */
@SystemApi
public class NanoAppFilter {

    // The appId, can be set to APP_ID_ANY
    private long mAppId;

    // Version to filter apps
    private int mAppVersion;

    // filtering spec for version
    private int mVersionRestrictionMask;

    // If APP_ID is any, then a match is performef with the vendor mask
    private long mAppIdVendorMask;

    // Id of the context hub this instance is expected on
    private int mContextHubId;

    /**
     * Flag indicating any version. With this flag set, all versions shall match provided version.
     */
    public static final int FLAGS_VERSION_ANY = -1;
    /**
     * If this flag is set, only versions strictly greater than the version specified shall match.
     */
    public static final int FLAGS_VERSION_GREAT_THAN  = 2;
    /**
     * If this flag is set, only versions strictly less than the version specified shall match.
     */
    public static final int FLAGS_VERSION_LESS_THAN   = 4;
    public static final int FLAGS_VERSION_STRICTLY_EQUAL = 8;

    /**
     * If this flag is set, only versions strictly equal to the version specified shall match.
     */
    public static final int APP_ANY = -1;

    /**
     * If this flag is set, all vendors shall match.
     */
    public static final int VENDOR_ANY = -1;

    /**
     * If this flag is set, any hub shall match.
     */
    public static final int HUB_ANY = -1;

    private NanoAppFilter(Parcel in) {
        mAppId = in.readLong();
        mAppVersion = in.readInt();
        mVersionRestrictionMask = in.readInt();
        mAppIdVendorMask = in.readInt();
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel out, int flags) {

        out.writeLong(mAppId);
        out.writeInt(mAppVersion);
        out.writeInt(mVersionRestrictionMask);
        out.writeLong(mAppIdVendorMask);
    }

    /**
     * Create a filter
     *
     * @param appId       application id
     * @param appVersion  application version
     * @param versionMask version
     * @param vendorMask  vendor
     */
    public NanoAppFilter(long appId, int appVersion, int versionMask, long vendorMask) {
        mAppId = appId;
        mAppVersion = appVersion;
        mVersionRestrictionMask = versionMask;
        mAppIdVendorMask = vendorMask;
    }

    private boolean versionsMatch(int versionRestrictionMask, int expected, int actual){
        // some refactoring of version restriction mask is needed, until then, return all
        return true;
    }
    /**
     * Test match method.
     *
     * @param info nano app instance info
     *
     * @return true if this is a match, false otherwise
     */
    public boolean testMatch(NanoAppInstanceInfo info) {
        if ((mContextHubId == HUB_ANY || info.getContexthubId() == mContextHubId) &&
                (mAppId == APP_ANY || info.getAppId() == mAppId) &&
               // (mAppIdVendorMask == VENDOR_ANY) TODO : Expose Vendor mask cleanly
                (versionsMatch(mVersionRestrictionMask, mAppVersion, info.getAppVersion()))) {
            return true;
        } else {
            return false;
        }
    }

    public static final Parcelable.Creator<NanoAppFilter> CREATOR
            = new Parcelable.Creator<NanoAppFilter>() {
        public NanoAppFilter createFromParcel(Parcel in) {
            return new NanoAppFilter(in);
        }

        public NanoAppFilter[] newArray(int size) {
            return new NanoAppFilter[size];
        }
    };
}
