/*
 * Copyright (C) 2019 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 androidx.camera.integration.view;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

/** The main activity. */
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    // Possible values for this intent key (case-insensitive): "PreviewView", "CameraView".
    private static final String INTENT_EXTRA_VIEW_TYPE = "view_type";
    private static final String VIEW_TYPE_PREVIEW_VIEW = "PreviewView";
    private static final String VIEW_TYPE_CAMERA_VIEW = "CameraView";

    private static final String[] REQUIRED_PERMISSIONS =
            new String[]{
                    Manifest.permission.CAMERA,
                    Manifest.permission.RECORD_AUDIO,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
            };
    private static final int REQUEST_CODE_PERMISSIONS = 10;

    private boolean mCheckedPermissions = false;
    private Mode mMode = Mode.CAMERA_VIEW;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Get extra option for checking whether it need to be implemented with PreviewView
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
            final String viewTypeString = bundle.getString(INTENT_EXTRA_VIEW_TYPE);
            final boolean isViewTypeValid =
                    viewTypeString != null && (viewTypeString.equalsIgnoreCase(
                            VIEW_TYPE_PREVIEW_VIEW) || viewTypeString.equalsIgnoreCase(
                            VIEW_TYPE_CAMERA_VIEW));
            if (isViewTypeValid && viewTypeString.equalsIgnoreCase(VIEW_TYPE_PREVIEW_VIEW)) {
                mMode = Mode.PREVIEW_VIEW;
            }
        }
        // TODO(b/173019455): make this penaltyDeath after we fix the IO in test apps.
        StrictMode.ThreadPolicy threadPolicy =
                new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build();
        StrictMode.setThreadPolicy(threadPolicy);
        if (null == savedInstanceState) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (allPermissionsGranted()) {
                    startFragment();
                } else if (!mCheckedPermissions) {
                    ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS,
                            REQUEST_CODE_PERMISSIONS);
                    mCheckedPermissions = true;
                }
            } else {
                startFragment();
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(
            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == REQUEST_CODE_PERMISSIONS) {
            if (allPermissionsGranted()) {
                startFragment();
            } else {
                report("Permissions not granted by the user.");
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(@NonNull Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.actionbar_menu, menu);
        return true;
    }

    @SuppressLint("NonConstantResourceId")
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.camera_view:
                mMode = Mode.CAMERA_VIEW;
                break;
            case R.id.preview_view:
                mMode = Mode.PREVIEW_VIEW;
                break;
            case R.id.camera_controller:
                mMode = Mode.CAMERA_CONTROLLER;
                break;
            case R.id.transform:
                mMode = Mode.TRANSFORM;
                break;
        }
        startFragment();
        return true;
    }

    private boolean allPermissionsGranted() {
        for (String permission : REQUIRED_PERMISSIONS) {
            if (ContextCompat.checkSelfPermission(this, permission)
                    != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    private void startFragment() {
        switch (mMode) {
            case CAMERA_VIEW:
                startFragment(R.string.camera_view, new CameraViewFragment());
                break;
            case PREVIEW_VIEW:
                startFragment(R.string.preview_view, new PreviewViewFragment());
                break;
            case CAMERA_CONTROLLER:
                startFragment(R.string.camera_controller, new CameraControllerFragment());
                break;
            case TRANSFORM:
                startFragment(R.string.transform, new TransformFragment());
        }
    }

    private void startFragment(int titleRes, Fragment fragment) {
        getSupportActionBar().setTitle(titleRes);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.content, fragment)
                .commit();
    }

    private void report(String msg) {
        Log.d(TAG, msg);
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    private enum Mode {
        CAMERA_VIEW, PREVIEW_VIEW, CAMERA_CONTROLLER, TRANSFORM
    }
}

@@ -1235,16 +1235,66 @@
 ragment;
+%0Aimport androidx.fragment.app.FragmentTransaction;
 %0A%0A/** Th
@@ -6065,32 +6065,74 @@
 tleRes);%0A       
+ FragmentTransaction fragmentTransaction =
  getSupportFragm
@@ -6143,33 +6143,16 @@
 anager()
-%0A                
 .beginTr
@@ -6162,16 +6162,17 @@
 action()
+;
 %0A       
@@ -6172,24 +6172,35 @@
         
-        
+fragmentTransaction
 .replace
@@ -6223,16 +6223,17 @@
 ragment)
+;
 %0A       
@@ -6237,26 +6237,280 @@
     
-        .commit();
+if (mCheckedPermissions && Build.VERSION.SDK_INT == Build.VERSION_CODES.M) %7B%0A            // For the codes, check the b/182981155 for the detail.%0A            fragmentTransaction.commitAllowingStateLoss();%0A        %7D else %7B%0A            fragmentTransaction.commit();%0A        %7D
 %0A   

Fix viewtestapp crash for 1st time launch on Android API 23