/*
 * Copyright (C) 2016 Google Inc.
 *
 * 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.googlecode.android_scripting.activity;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.ClipboardManager;
import android.util.TypedValue;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.googlecode.android_scripting.ActivityFlinger;
import com.googlecode.android_scripting.Log;
import com.googlecode.android_scripting.Process;
import com.googlecode.android_scripting.R;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;

public class LogcatViewer extends ListActivity {

  private List<String> mLogcatMessages;
  private int mOldLastPosition;
  private LogcatViewerAdapter mAdapter;
  private Process mLogcatProcess;

  private static enum MenuId {
    HELP, PREFERENCES, JUMP_TO_BOTTOM, SHARE, COPY;
    public int getId() {
      return ordinal() + Menu.FIRST;
    }
  }

  private class LogcatWatcher implements Runnable {
    @Override
    public void run() {
      mLogcatProcess = new Process();
      mLogcatProcess.setBinary(new File("/system/bin/logcat"));
      mLogcatProcess.start(null);
      try {
        BufferedReader br = new BufferedReader(new InputStreamReader(mLogcatProcess.getIn()));
        while (true) {
          final String line = br.readLine();
          if (line == null) {
            break;
          }
          runOnUiThread(new Runnable() {
            @Override
            public void run() {
              mLogcatMessages.add(line);
              mAdapter.notifyDataSetInvalidated();
              // This logic performs what transcriptMode="normal" should do. Since that doesn't seem
              // to work, we do it this way.
              int lastVisiblePosition = getListView().getLastVisiblePosition();
              int lastPosition = mLogcatMessages.size() - 1;
              if (lastVisiblePosition == mOldLastPosition || lastVisiblePosition == -1) {
                getListView().setSelection(lastPosition);
              }
              mOldLastPosition = lastPosition;
            }
          });
        }
      } catch (IOException e) {
        Log.e("Failed to read from logcat process.", e);
      } finally {
        mLogcatProcess.kill();
      }
    }
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    CustomizeWindow.requestCustomTitle(this, "Logcat", R.layout.logcat_viewer);
    mLogcatMessages = new LinkedList<String>();
    mOldLastPosition = 0;
    mAdapter = new LogcatViewerAdapter();
    setListAdapter(mAdapter);
    ActivityFlinger.attachView(getListView(), this);
    ActivityFlinger.attachView(getWindow().getDecorView(), this);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(Menu.NONE, MenuId.PREFERENCES.getId(), Menu.NONE, "Preferences").setIcon(
        android.R.drawable.ic_menu_preferences);
    menu.add(Menu.NONE, MenuId.JUMP_TO_BOTTOM.getId(), Menu.NONE, "Jump to Bottom").setIcon(
        android.R.drawable.ic_menu_revert);
    menu.add(Menu.NONE, MenuId.SHARE.getId(), Menu.NONE, "Share").setIcon(
        android.R.drawable.ic_menu_share);
    menu.add(Menu.NONE, MenuId.COPY.getId(), Menu.NONE, "Copy").setIcon(
        android.R.drawable.ic_menu_edit);
    return super.onCreateOptionsMenu(menu);
  }

  private String getAsString() {
    StringBuilder builder = new StringBuilder();
    for (String message : mLogcatMessages) {
      builder.append(message + "\n");
    }
    return builder.toString();
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    int itemId = item.getItemId();
    if (itemId == MenuId.JUMP_TO_BOTTOM.getId()) {
      getListView().setSelection(mLogcatMessages.size() - 1);
    } else if (itemId == MenuId.PREFERENCES.getId()) {
      startActivity(new Intent(this, Preferences.class));
    } else if (itemId == MenuId.SHARE.getId()) {
      Intent intent = new Intent(Intent.ACTION_SEND);
      intent.putExtra(Intent.EXTRA_TEXT, getAsString().toString());
      intent.putExtra(Intent.EXTRA_SUBJECT, "Logcat Dump");
      intent.setType("text/plain");
      startActivity(Intent.createChooser(intent, "Send Logcat to:"));
    } else if (itemId == MenuId.COPY.getId()) {
      ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
      clipboard.setText(getAsString());
      Toast.makeText(this, "Copied to clipboard", Toast.LENGTH_SHORT).show();
    }
    return super.onOptionsItemSelected(item);
  }

  @Override
  protected void onStart() {
    mLogcatMessages.clear();
    Thread logcatWatcher = new Thread(new LogcatWatcher());
    logcatWatcher.setPriority(Thread.NORM_PRIORITY - 1);
    logcatWatcher.start();
    mAdapter.notifyDataSetInvalidated();
    super.onStart();
  }

  @Override
  protected void onPause() {
    super.onPause();
    mLogcatProcess.kill();
  }

  private class LogcatViewerAdapter extends BaseAdapter {

    @Override
    public int getCount() {
      return mLogcatMessages.size();
    }

    @Override
    public Object getItem(int position) {
      return mLogcatMessages.get(position);
    }

    @Override
    public long getItemId(int position) {
      return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
      TextView view = new TextView(LogcatViewer.this);
      view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
      view.setText(mLogcatMessages.get(position));
      return view;
    }
  }
}
