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

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

import com.example.android.autobackupsample.MainActivityFragment;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;

/**
 * The purpose of AddFileActivity activity is to create a data file based on the
 * file name and size parameters specified as an Intent external parameters or with the
 * activity UI.
 * <p/>
 * The optional intent parameters are
 * {@link com.example.android.autobackupsample.AddFileActivity#FILE_NAME} and
 * {@link com.example.android.autobackupsample.AddFileActivity#FILE_SIZE_IN_BYTES}.
 * {@link com.example.android.autobackupsample.AddFileActivity#FILE_STORAGE}.
 * <p/>
 * The activity will return an
 * {@link com.example.android.autobackupsample.MainActivityFragment#ADD_FILE_RESULT_ERROR}
 * if intent parameters are specified incorrectly or it will display Toast messages to the user
 * if those parameters are specified via the activity UI.
 */
public class AddFileActivity extends Activity {

    private static final String TAG = "AutoBackupSample";

    /**
     * The intent parameter that specifies a file name. The file name must be unique for the
     * application internal directory.
     */
    public static final String FILE_NAME = "file_name";

    /**
     * The intent parameter that specifies a file size in bytes. The size must be a number
     * larger or equal to 0.
     */
    public static final String FILE_SIZE_IN_BYTES = "file_size_in_bytes";

    /**
     * The file storage is an optional parameter. It should be one of these:
     * "INTERNAL", "EXTERNAL", "DONOTBACKUP". The default option is "INTERNAL".
     */
    public static final String FILE_STORAGE = "file_storage";

    /**
     * A file size multiplier. It is used to calculate the total number of bytes to be added
     * to the file.
     */
    private int mSizeMultiplier = 1;

    /**
     * Defines File Storage options.
     */
    private static enum FileStorage {
        INTERNAL,
        EXTERNAL,
        DONOTBACKUP;
    }

    /**
     * Contains a selected by a user file storage option.
     */
    private FileStorage mFileStorage = FileStorage.INTERNAL;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_file);
        initFileSizeSpinner();
        initFileStorageSpinner();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // If an intent has extra parameters, create the file and finish the activity.
        if (getIntent().hasExtra(FILE_NAME) && getIntent().hasExtra(FILE_SIZE_IN_BYTES)) {
            String fileName = getIntent().getStringExtra(FILE_NAME);
            String sizeInBytesParamValue = getIntent().getStringExtra(FILE_SIZE_IN_BYTES);
            String fileStorageParamValue = FileStorage.INTERNAL.toString();

            if (getIntent().hasExtra(FILE_STORAGE)) {
                fileStorageParamValue = getIntent().getStringExtra(FILE_STORAGE);
            }

            if (TextUtils.isEmpty(fileName) ||
                    isFileExists(fileName) ||
                    !isSizeValid(sizeInBytesParamValue) ||
                    !isFileStorageParamValid(fileStorageParamValue)) {
                setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR);
                finish();
                return;
            }

            mFileStorage = FileStorage.valueOf(fileStorageParamValue);

            if (mFileStorage == FileStorage.EXTERNAL && !Utils.isExternalStorageAvailable()) {
                setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR);
                finish();
                return;
            }

            createFileWithRandomDataAndFinishActivity(fileName, mFileStorage,
                    sizeInBytesParamValue);
        }
    }

    /**
     * A handler function for a Create File button click event.
     *
     * @param view a reference to the Create File button view.
     */
    public void onCreateFileButtonClick(View view) {
        EditText fileNameEditText = (EditText) findViewById(R.id.file_name);
        EditText fileSizeEditText = (EditText) findViewById(R.id.file_size);
        String fileName = fileNameEditText.getText().toString();
        String fileSizeEditTextValue = fileSizeEditText.getText().toString();

        if (TextUtils.isEmpty(fileName) || isFileExists(fileName)) {
            Toast toast = Toast.makeText(this, getText(R.string.file_exists), Toast.LENGTH_LONG);
            toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
            toast.show();
            return;
        }

        if (!isSizeValid(fileSizeEditTextValue)) {
            Toast toast = Toast.makeText(this, getText(R.string.file_size_is_invalid),
                    Toast.LENGTH_LONG);
            toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
            toast.show();
            return;
        }

        long fileSize = Long.parseLong(fileSizeEditTextValue) * mSizeMultiplier;

        if (mFileStorage == FileStorage.EXTERNAL && !Utils.isExternalStorageAvailable()) {
            Toast toast = Toast.makeText(this,
                    getText(R.string.external_storage_unavailable), Toast.LENGTH_LONG);
            toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
            toast.show();
            return;
        }

        createFileWithRandomDataAndFinishActivity(fileName, mFileStorage, String.valueOf(fileSize));
    }

    private void initFileSizeSpinner() {
        Spinner spinner = (Spinner) findViewById(R.id.file_size_spinner);
        final ArrayAdapter<CharSequence> adapter =
                ArrayAdapter.createFromResource(this, R.array.file_size_array,
                        android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String sizeMeasure = adapter.getItem(position).toString();
                mSizeMultiplier = (int) Math.pow(1024, position);
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, String.format("Selected: %s, %d", sizeMeasure,
                            mSizeMultiplier));
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
    }

    private void initFileStorageSpinner() {
        Spinner spinner = (Spinner) findViewById(R.id.storage_spinner);
        final ArrayAdapter<CharSequence> adapter =
                ArrayAdapter.createFromResource(this, R.array.file_storage_array,
                        android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                mFileStorage = FileStorage.values()[position];
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
    }

    private void createFileWithRandomDataAndFinishActivity(String fileName, FileStorage storage,
                                                           String sizeInBytes) {
        long size = Long.valueOf(sizeInBytes);
        File file = null;
        FileOutputStream out = null;
        BufferedOutputStream bufOut = null;
        try {
            switch (storage) {
                case INTERNAL:
                    file = getInternalFile(fileName);
                    out = openFileOutput(file.getName(), Context.MODE_PRIVATE);
                    break;
                case EXTERNAL:
                    assert Utils.isExternalStorageAvailable() :
                            "The external storage is not available";
                    File externalAppDir = getExternalFilesDir(null);
                    file = new File(externalAppDir, fileName);
                    out = new FileOutputStream(file);
                    break;
                case DONOTBACKUP:
                    file = new File(getNoBackupFilesDir(), fileName);
                    out = new FileOutputStream(file);
                    break;
            }

            if (file == null || out == null) {
                Log.d(TAG, "Unable to create file output stream");
                // Returning back to the caller activity.
                setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR);
                finish();
                return;
            }

            bufOut = new BufferedOutputStream(out);
            for (int i = 0; i < size; i++) {
                byte b = (byte) (255 * Math.random());
                bufOut.write(b);
            }

            String message = String.format("File created: %s, size: %s bytes",
                    file.getAbsolutePath(), sizeInBytes);

            Toast toast = Toast.makeText(this, message, Toast.LENGTH_LONG);
            toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
            toast.show();
            Log.d(TAG, message);

            // Returning back to the caller activity.
            setResult(MainActivityFragment.ADD_FILE_RESULT_SUCCESS);
            finish();
        } catch (Exception e) {
            Log.e(TAG, e.getMessage(), e);
            // Returning back to the caller activity.
            setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR);
            finish();
        } finally {
            if (bufOut != null) {
                try {
                    bufOut.close();
                } catch (Exception e) {
                    // Ignore.
                }
            }
        }
    }

    private boolean isFileExists(String fileName) {
        File file = getInternalFile(fileName);
        if (file.exists()) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "This file exists: " + file.getName());
            }
            return true;
        }
        return false;
    }

    private boolean isSizeValid(String sizeInBytesParamValue) {
        long sizeInBytes = 0;
        try {
            sizeInBytes = Long.valueOf(sizeInBytesParamValue);
        } catch (NumberFormatException e) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Invalid file size: " + sizeInBytesParamValue);
            }
            return false;
        }

        // Validate file size value. It should be 0 or a positive number.
        if (sizeInBytes < 0) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Invalid file size: " + sizeInBytes);
            }
            return false;
        }
        return true;
    }

    private boolean isFileStorageParamValid(String fileStorage) {
        try {
            mFileStorage = FileStorage.valueOf(fileStorage);
        } catch (IllegalArgumentException e) {
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Invalid file storage: " + fileStorage);
            }
            return false;
        }
        return true;
    }

    private File getInternalFile(String fileName) {
        File internalAppDir = getFilesDir();
        return new File(internalAppDir, fileName);
    }

}