/*
 * Copyright (C) 2017 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.compatibility.common.util;

import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Host-side utility class for reading properties and gathering information for testing
 * Android device compatibility.
 */
public class PropertyUtil {

    /**
     * Name of read-only property detailing the first API level for which the product was
     * shipped. Property should be undefined for factory ROM products.
     */
    public static final String FIRST_API_LEVEL = "ro.product.first_api_level";
    private static final String BUILD_TAGS_PROPERTY = "ro.build.tags";
    private static final String BUILD_TYPE_PROPERTY = "ro.build.type";
    private static final String MANUFACTURER_PROPERTY = "ro.product.manufacturer";
    private static final String TAG_DEV_KEYS = "dev-keys";

    public static final String GOOGLE_SETTINGS_QUERY =
            "content query --uri content://com.google.settings/partner";

    /** Returns whether the device build is a user build */
    public static boolean isUserBuild(ITestDevice device) throws DeviceNotAvailableException {
        return propertyEquals(device, BUILD_TYPE_PROPERTY, "user");
    }

    /** Returns whether this build is built with dev-keys */
    public static boolean isDevKeysBuild(ITestDevice device) throws DeviceNotAvailableException {
        String buildTags = device.getProperty(BUILD_TAGS_PROPERTY);
        for (String tag : buildTags.split(",")) {
            if (TAG_DEV_KEYS.equals(tag.trim())) {
                return true;
            }
        }
        return false;
    }

    /**
     * Return the first API level for this product. If the read-only property is unset,
     * this means the first API level is the current API level, and the current API level
     * is returned.
     */
    public static int getFirstApiLevel(ITestDevice device) throws DeviceNotAvailableException {
        String propString = device.getProperty(FIRST_API_LEVEL);
        return (propString == null) ? device.getApiLevel() : Integer.parseInt(propString);
    }

    /**
     * Return the manufacturer of this product. If unset, return null.
     */
    public static String getManufacturer(ITestDevice device) throws DeviceNotAvailableException {
        return device.getProperty(MANUFACTURER_PROPERTY);
    }

    /** Returns a mapping from client ID names to client ID values */
    public static Map<String, String> getClientIds(ITestDevice device)
            throws DeviceNotAvailableException {
        Map<String,String> clientIds = new HashMap<>();
        String queryOutput = device.executeShellCommand(GOOGLE_SETTINGS_QUERY);
        for (String line : queryOutput.split("[\\r?\\n]+")) {
            // Expected line format: "Row: 1 _id=123, name=<property_name>, value=<property_value>"
            Pattern pattern = Pattern.compile("name=([a-z_]*), value=(.*)$");
            Matcher matcher = pattern.matcher(line);
            if (matcher.find()) {
                String name = matcher.group(1);
                String value = matcher.group(2);
                if (name.contains("client_id")) {
                    clientIds.put(name, value); // only add name-value pair for client ids
                }
            }
        }
        return clientIds;
    }

    /** Returns whether the property exists on this device */
    public static boolean propertyExists(ITestDevice device, String property)
            throws DeviceNotAvailableException {
        return device.getProperty(property) != null;
    }

    /** Returns whether the property value is equal to a given string */
    public static boolean propertyEquals(ITestDevice device, String property, String value)
            throws DeviceNotAvailableException {
        if (value == null) {
            return !propertyExists(device, property); // null value implies property does not exist
        }
        return value.equals(device.getProperty(property));
    }

    /**
     * Returns whether the property value matches a given regular expression. The method uses
     * String.matches(), requiring a complete match (i.e. expression matches entire value string)
     */
    public static boolean propertyMatches(ITestDevice device, String property, String regex)
            throws DeviceNotAvailableException {
        if (regex == null || regex.isEmpty()) {
            // null or empty pattern implies property does not exist
            return !propertyExists(device, property);
        }
        String value = device.getProperty(property);
        return (value == null) ? false : value.matches(regex);
    }
}
