/*
 * Copyright (C) 2011 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.providers.contacts;

import android.content.UriMatcher;
import android.net.Uri;
import android.provider.ContactsContract;

import com.google.android.collect.Lists;
import com.google.android.collect.Maps;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * A subclass of URI matcher with additional logic and awareness around profile-specific URIs.
 */
public class ProfileAwareUriMatcher extends UriMatcher {

    private static final Pattern PATH_SPLIT_PATTERN = Pattern.compile("/");

    private static final String PROFILE_SEGMENT = "profile";
    private static final String LOOKUP_SEGMENT = "lookup";
    private static final String VCARD_SEGMENT = "as_vcard";
    private static final String ID_SEGMENT = "#";
    private static final String WILDCARD_SEGMENT = "*";

    // URIs matching to these constants must always use the profile database.
    private static final List<Integer> PROFILE_URIS = Lists.newArrayList();

    // URIs in this map will direct to the profile database if the ID (which is at the segment
    // path with the location specified by the value in the map) is in the profile ID-space.
    private static final Map<Integer, Integer> PROFILE_URI_ID_MAP = Maps.newHashMap();

    // URIs in this map will direct to the profile database if the lookup key (which is at the
    // segment path with the location specified by the value in the map) is the special profile
    // lookup key (see {@link ProfileAggregator#PROFILE_LOOKUP_KEY}).
    private static final Map<Integer, Integer> PROFILE_URI_LOOKUP_KEY_MAP = Maps.newHashMap();

    /**
     * Creates the root node of the URI tree.
     *
     * @param code the code to match for the root URI
     */
    public ProfileAwareUriMatcher(int code) {
        super(code);
    }

    @Override
    public void addURI(String authority, String path, int code) {
        super.addURI(authority, path, code);

        // Do a second tokenization pass to determine whether the URI may apply to profiles.
        if (path != null) {
            String newPath = path;
            // Strip leading slash if present.
            if (path.length() > 0 && path.charAt(0) == '/') {
                newPath = path.substring(1);
            }
            String[] tokens = PATH_SPLIT_PATTERN.split(newPath);

            if (tokens != null) {

                // Keep track of whether we've passed a "lookup" token in the path; wildcards after
                // that token will be interpreted as lookup keys.  For our purposes, vcard paths
                // also count as lookup tokens, since the vcard is specified by lookup key.
                boolean afterLookup = false;
                for (int i = 0; i < tokens.length; i++) {
                    String token = tokens[i];
                    if (token.equals(PROFILE_SEGMENT)) {
                        PROFILE_URIS.add(code);
                        return;
                    } else if (token.equals(LOOKUP_SEGMENT)
                            || token.equals(VCARD_SEGMENT)) {
                        afterLookup = true;
                        continue;
                    } else if (token.equals(ID_SEGMENT)) {
                        PROFILE_URI_ID_MAP.put(code, i);
                    } else if (token.equals(WILDCARD_SEGMENT)) {
                        if (afterLookup) {
                            PROFILE_URI_LOOKUP_KEY_MAP.put(code, i);
                        }
                    }
                    afterLookup = false;
                }
            }
        }
    }

    /**
     * Determines whether the given URI is intended for the profile DB rather than contacts.
     * This is true under any of three conditions:
     * 1. The URI itself is specifically for the profile (it contains a "profile" segment).
     * 2. The URI contains ID references that are in the profile ID-space.
     * 3. The URI contains lookup key references that match the special profile lookup key.
     * @param uri The URI to examine.
     * @return Whether the operation for this URI is intended for the profile DB.
     */
    public boolean mapsToProfile(Uri uri) {
        int match = match(uri);
        if (PROFILE_URIS.contains(match)) {
            return true;
        } else if (PROFILE_URI_ID_MAP.containsKey(match)) {
            int idSegment = PROFILE_URI_ID_MAP.get(match);
            long id = Long.parseLong(uri.getPathSegments().get(idSegment));
            if (ContactsContract.isProfileId(id)) {
                return true;
            }
        } else if (PROFILE_URI_LOOKUP_KEY_MAP.containsKey(match)) {
            int lookupKeySegment = PROFILE_URI_LOOKUP_KEY_MAP.get(match);
            String lookupKey = uri.getPathSegments().get(lookupKeySegment);
            if (ContactLookupKey.PROFILE_LOOKUP_KEY.equals(lookupKey)) {
                return true;
            }
        }
        return false;
    }
}
