/*
 * 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.example.android.autofillframework;

import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.app.assist.AssistStructure.WindowNode;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewStructure.HtmlInfo;
import android.view.autofill.AutofillValue;

import java.util.Arrays;
import java.util.Set;

public final class CommonUtil {

    public static final String TAG = "AutofillSample";
    public static final boolean DEBUG = true;
    public static final String EXTRA_DATASET_NAME = "dataset_name";
    public static final String EXTRA_FOR_RESPONSE = "for_response";

    private static void bundleToString(StringBuilder builder, Bundle data) {
        final Set<String> keySet = data.keySet();
        builder.append("[Bundle with ").append(keySet.size()).append(" keys:");
        for (String key : keySet) {
            builder.append(' ').append(key).append('=');
            Object value = data.get(key);
            if ((value instanceof Bundle)) {
                bundleToString(builder, (Bundle) value);
            } else {
                builder.append((value instanceof Object[])
                        ? Arrays.toString((Object[]) value) : value);
            }
        }
        builder.append(']');
    }

    public static String bundleToString(Bundle data) {
        if (data == null) {
            return "N/A";
        }
        final StringBuilder builder = new StringBuilder();
        bundleToString(builder, data);
        return builder.toString();
    }

    public static String getTypeAsString(int type) {
        switch (type) {
            case View.AUTOFILL_TYPE_TEXT:
                return "TYPE_TEXT";
            case View.AUTOFILL_TYPE_LIST:
                return "TYPE_LIST";
            case View.AUTOFILL_TYPE_NONE:
                return "TYPE_NONE";
            case View.AUTOFILL_TYPE_TOGGLE:
                return "TYPE_TOGGLE";
            case View.AUTOFILL_TYPE_DATE:
                return "TYPE_DATE";
        }
        return "UNKNOWN_TYPE";
    }

    private static String getAutofillValueAndTypeAsString(AutofillValue value) {
        if (value == null) return "null";

        StringBuilder builder = new StringBuilder(value.toString()).append( '(');
        if (value.isText()) {
            builder.append("isText");
        } else if (value.isDate()) {
            builder.append("isDate");
        } else if (value.isToggle()) {
            builder.append("isToggle");
        } else if (value.isList()) {
            builder.append("isList");
        }
        return builder.append(')').toString();
    }

    public static void dumpStructure(AssistStructure structure) {
        int nodeCount = structure.getWindowNodeCount();
        Log.v(TAG, "dumpStructure(): component=" + structure.getActivityComponent()
                + " numberNodes=" + nodeCount);
        for (int i = 0; i < nodeCount; i++) {
            Log.v(TAG, "node #" + i);
            WindowNode node = structure.getWindowNodeAt(i);
            dumpNode("  ", node.getRootViewNode());
        }
    }

    private static void dumpNode(String prefix, ViewNode node) {
        StringBuilder builder = new StringBuilder();
        String[] hints = node.getAutofillHints();
        builder.append(prefix)
                .append("autoFillId: ").append(node.getAutofillId())
                .append("\tidEntry: ").append(node.getIdEntry())
                .append("\tid: ").append(node.getId())
                .append("\thints: ").append(hints == null ? "N/A" : Arrays.toString(hints))
                .append("\tclassName: ").append(node.getClassName())
                .append('\n');

        builder.append(prefix)
                .append("focused: ").append(node.isFocused())
                .append("\tvisibility").append(node.getVisibility())
                .append("\tchecked: ").append(node.isChecked())
                .append("\tURL: ").append(node.getWebDomain())
                .append('\n');

        HtmlInfo htmlInfo = node.getHtmlInfo();

        if (htmlInfo != null) {
            builder.append(prefix)
                    .append("HTML TAG: ").append(htmlInfo.getTag())
                    .append(" attrs: ").append(htmlInfo.getAttributes())
                    .append('\n');
        }

        CharSequence[] options = node.getAutofillOptions();
        builder.append(prefix).append("afType: ").append(getTypeAsString(node.getAutofillType()))
                .append("\tafValue:")
                .append(getAutofillValueAndTypeAsString(node.getAutofillValue()))
                .append("\tafOptions:").append(options == null ? "N/A" : Arrays.toString(options))
                .append("\tinputType:").append(node.getInputType())
                .append('\n');

        int numberChildren = node.getChildCount();
        builder.append(prefix).append("# children: ").append(numberChildren)
                .append("\ttext: ").append(node.getText())
                .append('\n');

        Log.v(TAG, builder.toString());
        final String prefix2 = prefix + "  ";
        for (int i = 0; i < numberChildren; i++) {
            Log.v(TAG, prefix + "child #" + i);
            dumpNode(prefix2, node.getChildAt(i));
        }
    }
}