/*
 * ************************************************************************
 *
 * ADOBE SYSTEMS INCORPORATED
 * Copyright 2013 Adobe Systems Incorporated
 * All Rights Reserved.
 * NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the 
 * terms of the Adobe license agreement accompanying it.  If you have received this file from a 
 * source other than Adobe, then your use, modification, or distribution of it requires the prior 
 * written permission of Adobe.
 *
 **************************************************************************
 */

package com.adobe.primetime.reference.ui.log;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import android.widget.Toast;

import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.support.v7.app.ActionBar;

import com.adobe.mediacore.Version;
import com.adobe.primetime.reference.R;
import com.adobe.primetime.reference.PrimetimeReference;
import com.adobe.primetime.reference.ui.catalog.CatalogActivity;
import com.adobe.primetime.reference.ui.settings.SettingsActivity;
import com.adobe.primetime.reference.logging.Logger;
import com.adobe.primetime.reference.logging.InMemoryLogger;
import com.adobe.primetime.reference.logging.InMemoryLogger.LogEntry;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class LogActivity extends AppCompatActivity {
	private static final String LOG_TAG = PrimetimeReference.LOG_APP_NAME + "LogActivity";

	private List<LogEntry> logList = new ArrayList<LogEntry>();
	private LogListAdapter logListAdapter;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_log);

		logListAdapter = new LogListAdapter(this, R.layout.item_list_settings, logList);
		ListView lvLogList = (ListView) findViewById(R.id.lvLogList);
		lvLogList.setAdapter(logListAdapter);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.actionbar_log, menu);

		ActionBar actionBar = getSupportActionBar();
		actionBar.setDisplayHomeAsUpEnabled(true);

		return true;
	}

	@Override
	protected void onStart() {
		super.onStart();
		updateUI();
	}

	@Override
	protected void onStop() {
		super.onStop();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Intent intent;

		switch (item.getItemId()) {
		case android.R.id.home:
			intent = new Intent(this, CatalogActivity.class);
			intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(intent);
			return true;

		case R.id.ActionBarLogRefresh:
			PrimetimeReference.logger.d(LOG_TAG + "#onOptionsItemSelected",
					"Refresh log action bar item activated.");

			updateUI();
			return true;

		case R.id.ActionBarLogDelete:
			PrimetimeReference.logger.i(LOG_TAG + "#onOptionsItemSelected",
					"Delete log action bar item activated.");

			((InMemoryLogger)PrimetimeReference.logger).clear();
			updateUI();

			Toast.makeText(this, "Log history cleared.", Toast.LENGTH_SHORT)
					.show();
			return true;

		case R.id.ActionBarLogSave:
			PrimetimeReference.logger.i(LOG_TAG + "#onOptionsItemSelected",
					"Save log action bar item activated.");

			saveLogToFile();

			return true;

		case R.id.ActionBarSettings:
			PrimetimeReference.logger.i(LOG_TAG + "#onOptionsItemSelected",
					"Settings action bar item activated.");

			intent = new Intent(this, SettingsActivity.class);
			startActivity(intent);
			return true;

		case R.id.ActionBarAbout:
			PrimetimeReference.logger.i(LOG_TAG + "#onOptionsItemSelected",
					"About action bar item activated.");
			PrimetimeReference.showAbout(this);
			return true;

		default:
			return super.onOptionsItemSelected(item);
		}
	}

	private void updateUI() {
		logList.clear();
		logList.addAll(getAndFilterLogEntries());
		logListAdapter.notifyDataSetChanged();
	}

	/**
	 * @return the verbosity level saved in the settings.
	 */
	public static Logger.Verbosity getVerbosity(Context context) {
		SharedPreferences sharedPreferences = PreferenceManager
				.getDefaultSharedPreferences(context);
		String logVerbosityString = sharedPreferences.getString(
				PrimetimeReference.SETTINGS_LOG_VERBOSITY, Logger.Verbosity.INFO.getLevel()
						+ "");
		int level;
		try {
			level = Integer.parseInt(logVerbosityString);
		} catch (Exception e) {
			PrimetimeReference.logger.w(LOG_TAG + "#getVerbosity", "Exception triggered: "
					+ e.getMessage());
			level = Logger.Verbosity.INFO.getLevel();
		}
		return Logger.Verbosity.values()[level];
	}

	/**
	 * @return the filtered log entries, based on the verbosity level saved in
	 *         the settings.
	 */
	private List<LogEntry> getAndFilterLogEntries() {
		List<LogEntry> entries = ((InMemoryLogger)PrimetimeReference.logger).getEntries();
		List<LogEntry> filteredEntries = new ArrayList<LogEntry>();
		Logger.Verbosity verbosity = getVerbosity(this);
		switch (verbosity) {
		case NONE:
			// Return empty list.
			return filteredEntries;
		case DEBUG:
			// Return all entries.
			return entries;
		case INFO:
		case WARN:
		case ERROR:
			for (LogEntry entry : entries) {
				if (entry.getVerbosity().getLevel() <= verbosity.getLevel()) {
					filteredEntries.add(entry);
				}
			}
		}
		return filteredEntries;
	}

	private void saveLogToFile() {
		String fileName = "pmp_log.csv";
		String logDirName = getResources().getString(R.string.logDirName);
		String columnSeparator = getResources().getString(
				R.string.logColumnSeparator);

		try {
			new File(logDirName).mkdirs();
			FileOutputStream outputStream = new FileOutputStream(logDirName
					+ fileName);

			PrintStream printStream = new PrintStream(outputStream);
			List<LogEntry> entries = getAndFilterLogEntries();
			for (LogEntry entry : entries) {
				String record = entry.getVerbosity().toString()
						+ columnSeparator + entry.getDateTime()
						+ columnSeparator + entry.getTag() + columnSeparator
						+ entry.getMessage();
				printStream.println(record);
			}

			outputStream.flush();
			outputStream.close();

			Intent sendIntent = new Intent(Intent.ACTION_SEND);
			sendIntent.setType("text/plain");
			sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Primetime Reference Log");
			
			StringBuilder message = new StringBuilder();
			message.append("TVSDK version: ").append(Version.getVersion()).append('\n');
			message.append("Product: ").append(Build.PRODUCT).append('\n');
			message.append("OS: ").append(Build.VERSION.RELEASE).append('\n');
			message.append("SDK: ").append(Build.VERSION.SDK_INT).append('\n');
			
			sendIntent.putExtra(Intent.EXTRA_TEXT, message.toString());
			sendIntent.putExtra(Intent.EXTRA_STREAM,
					Uri.parse("file://" + logDirName + fileName));
			startActivity(Intent.createChooser(sendIntent, "Email:"));			
								
		} catch (FileNotFoundException e) {
			PrimetimeReference.logger.i(LOG_TAG + "#onOptionsItemSelected",
					"Cannot find the log file: " + e.getMessage());
			Toast.makeText(this, "Failed to save the log history.",
					Toast.LENGTH_SHORT).show();
		} catch (IOException e) {
			PrimetimeReference.logger.i(LOG_TAG + "#onOptionsItemSelected",
					"Cannot write the log file: " + e.getMessage());
			Toast.makeText(this, "Failed to save the log history.",
					Toast.LENGTH_SHORT).show();
		}
	}
}
