/*
 * Copyright (C) 2013 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.settings;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.SystemProperties;
import androidx.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.Locale;

/**
 * {@link Activity} that displays regulatory information for the "Regulatory information"
 * preference item, and when "*#07#" is dialed on the Phone keypad. To enable this feature,
 * set the "config_show_regulatory_info" boolean to true in a device overlay resource, and in the
 * same overlay, either add a drawable named "regulatory_info.png" containing a graphical version
 * of the required regulatory info (If ro.bootloader.hardware.sku property is set use
 * "regulatory_info_<sku>.png where sku is ro.bootloader.hardware.sku property value in lowercase"),
 * or add a string resource named "regulatory_info_text" with an HTML version of the required
 * information (text will be centered in the dialog).
 */
public class RegulatoryInfoDisplayActivity extends Activity implements
        DialogInterface.OnDismissListener {

    private final String REGULATORY_INFO_RESOURCE = "regulatory_info";
    private static final String DEFAULT_REGULATORY_INFO_FILEPATH =
            "/data/misc/elabel/regulatory_info.png";
    private static final String REGULATORY_INFO_FILEPATH_TEMPLATE =
            "/data/misc/elabel/regulatory_info_%s.png";

    /**
     * Display the regulatory info graphic in a dialog window.
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Resources resources = getResources();

        if (!resources.getBoolean(R.bool.config_show_regulatory_info)) {
            finish();   // no regulatory info to display for this device
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(this)
                .setTitle(R.string.regulatory_labels)
                .setOnDismissListener(this);

        boolean regulatoryInfoDrawableExists = false;

        final String regulatoryInfoFile = getRegulatoryInfoImageFileName();
        final Bitmap regulatoryInfoBitmap = BitmapFactory.decodeFile(regulatoryInfoFile);

        if (regulatoryInfoBitmap != null) {
            regulatoryInfoDrawableExists = true;
        }

        int resId = 0;
        if (!regulatoryInfoDrawableExists) {
            resId = getResourceId();
        }
        if (resId != 0) {
            try {
                Drawable d = getDrawable(resId);
                // set to false if the width or height is <= 2
                // (missing PNG can return an empty 2x2 pixel Drawable)
                regulatoryInfoDrawableExists = (d.getIntrinsicWidth() > 2
                        && d.getIntrinsicHeight() > 2);
            } catch (Resources.NotFoundException ignored) {
                regulatoryInfoDrawableExists = false;
            }
        }

        CharSequence regulatoryText = resources.getText(R.string.regulatory_info_text);

        if (regulatoryInfoDrawableExists) {
            View view = getLayoutInflater().inflate(R.layout.regulatory_info, null);
            ImageView image = view.findViewById(R.id.regulatoryInfo);
            if (regulatoryInfoBitmap != null) {
                image.setImageBitmap(regulatoryInfoBitmap);
            } else {
                image.setImageResource(resId);
            }
            builder.setView(view);
            builder.show();
        } else if (regulatoryText.length() > 0) {
            builder.setMessage(regulatoryText);
            AlertDialog dialog = builder.show();
            // we have to show the dialog first, or the setGravity() call will throw a NPE
            TextView messageText = (TextView) dialog.findViewById(android.R.id.message);
            messageText.setGravity(Gravity.CENTER);
        } else {
            // neither drawable nor text resource exists, finish activity
            finish();
        }
    }

    private int getResourceId() {
        // Use regulatory_info by default.
        int resId = getResources().getIdentifier(
                REGULATORY_INFO_RESOURCE, "drawable", getPackageName());

        // When hardware sku property exists, use regulatory_info_<sku> resource if valid.
        final String sku = getSku();
        if (!TextUtils.isEmpty(sku)) {
            String regulatory_info_res = REGULATORY_INFO_RESOURCE + "_" + sku.toLowerCase();
            int id = getResources().getIdentifier(
                    regulatory_info_res, "drawable", getPackageName());
            if (id != 0) {
                resId = id;
            }
        }
        return resId;
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        finish();   // close the activity
    }

    @VisibleForTesting
    public static String getSku() {
        return SystemProperties.get("ro.boot.hardware.sku", "");
    }

    @VisibleForTesting
    public static String getRegulatoryInfoImageFileName() {
        final String sku = getSku();
        if (TextUtils.isEmpty(sku)) {
            return DEFAULT_REGULATORY_INFO_FILEPATH;
        } else {
            return String.format(Locale.US, REGULATORY_INFO_FILEPATH_TEMPLATE,
                    sku.toLowerCase());
        }
    }
}
