// Copyright (C) 2016 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.google.reviewit;

import android.content.Intent;
import android.graphics.Paint;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.text.util.Linkify;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gerrit.extensions.common.FileInfo;
import com.google.reviewit.app.ActionHandler;
import com.google.reviewit.app.Change;
import com.google.reviewit.util.ChangeUtil;
import com.google.reviewit.widget.ChangeBox;
import com.google.reviewit.util.FormatUtil;
import com.google.reviewit.util.TaskObserver;
import com.google.reviewit.util.WidgetUtil;
import com.google.reviewit.widget.ApprovalsView;
import com.google.reviewit.widget.ZoomHandler;

import java.util.Map;
import java.util.regex.Pattern;

import static com.google.reviewit.util.LayoutUtil.matchAndWrapTableLayout;
import static com.google.reviewit.util.LayoutUtil.matchAndWrapTableRowLayout;
import static com.google.reviewit.util.WidgetUtil.setGone;
import static com.google.reviewit.util.WidgetUtil.setVisible;

/**
 * Fragment to show details of a change.
 */
public class DetailedChangeFragment extends BaseFragment implements
    OnBackPressedAware, DispatchTouchEventAware {
  private static final String TAG = DetailedChangeFragment.class.getName();

  private static final int PAGE_SIZE = 10;
  private static final Pattern PATTERN_CHANGE_ID =
      Pattern.compile("I[0-9a-f]{5,40}");
  private static final String PART_LINK = "(?:"
      + "[a-zA-Z0-9$_+!*'%;:@=?#/~-]"
      + "|&(?!lt;|gt;)"
      + "|[.,](?!(?:\\s|$))"
      + ")";
  private static final Pattern PATTERN_LINK = Pattern.compile(
      "https?://"
      + PART_LINK + "{2,}"
      + "(?:[(]" + PART_LINK + "*" + "[)])*"
      + PART_LINK + "*");
  private static final Pattern PATTERN_EMAIL =
      Pattern.compile("[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}",
          Pattern.CASE_INSENSITIVE);


  private ZoomHandler zoomHandler;

  @Override
  protected @LayoutRes int getLayout() {
    return R.layout.content_detailed_change;
  }

  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    Change change = getApp().getActionHandler().getCurrentChange();
    setTitle(getString(R.string.detailed_change_title, change.info._number));
    setHasOptionsMenu(true);
    init();
    zoomHandler = new ZoomHandler(v(R.id.scrollContent));
    TaskObserver.enableProgressBar(getWindow());

    try {
      ChangeUtil.colorBackground(root, change);
      ((ChangeBox) v(R.id.changeBox)).display(getApp(), change);
      linkify();
      displayChangeUrl(change);
      ((ApprovalsView) v(R.id.approvals)).displayApprovals(getApp(),
          change.info, this);
      displayFiles(change, 1, false);
      // TODO show further change info, e.g. summary comments, hashtags,
      // related changes
    } catch (Throwable t) {
      Log.e(TAG, "Failed to display change", t);
      display(ErrorFragment.create(t));
    }
  }

  @Override
  public void dispatchTouchEvent(MotionEvent event) {
    zoomHandler.dispatchTouchEvent(event);
  }

  private void init() {
    TextView commitMsg = (TextView) v(R.id.commitMessage);
    commitMsg.setLinksClickable(true);

    v(R.id.reviewButton).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        display(UnifiedDiffFragment.class);
      }
    });

    WidgetUtil.underline(tv(R.id.showMore));
    WidgetUtil.underline(tv(R.id.showAll));
  }

  private void linkify() {
    TextView commitMsg = tv(R.id.commitMessage);
    Linkify.addLinks(commitMsg, PATTERN_CHANGE_ID, getServerUrl() + "#/q/");
    Linkify.addLinks(commitMsg, PATTERN_LINK, "");
    Linkify.addLinks(commitMsg, PATTERN_EMAIL, "");
  }

  private void displayChangeUrl(Change change) {
    WidgetUtil.setText(v(R.id.changeUrl), change.getUrl(getServerUrl()));
    setVisible(v(R.id.changeUrlBox));
  }

  private String getServerUrl() {
    String serverUrl = getApp().getConfigManager().getServerConfig().url;
    return FormatUtil.ensureSlash(serverUrl);
  }

  private void displayFiles(
      final Change change, final int page, boolean showAll) {
    TableLayout tl = (TableLayout) v(R.id.filesTable);
    Map<String, FileInfo> files = change.currentRevision().files;
    int count = 0;
    for (Map.Entry<String, FileInfo> e : files.entrySet()) {
      count++;
      if (count <= (page - 1) * PAGE_SIZE) {
        continue;
      }
      if (!showAll && count > page * PAGE_SIZE) {
        break;
      }
      addFileRow(tl, e.getKey(), e.getValue());
    }
    if (!showAll && files.size() > page * PAGE_SIZE) {
      WidgetUtil.setText(v(R.id.showAll),
          getString(R.string.show_all, files.size() - page * PAGE_SIZE));
      setVisible(v(R.id.fileButtons));
      v(R.id.showAll).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          displayFiles(change, page + 1, true);
        }
      });
      if (files.size() > (page + 1) * PAGE_SIZE) {
        WidgetUtil.setText(v(R.id.showMore),
            getString(R.string.show_more, PAGE_SIZE));
        setVisible(v(R.id.showMoreArea, R.id.showMore));
        v(R.id.showMore).setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
            displayFiles(change, page + 1, false);
          }
        });
      } else {
        setGone(v(R.id.showMoreArea, R.id.showMore));
      }
    } else {
      setGone(v(R.id.fileButtons));
    }
  }

  private void addFileRow(TableLayout tl, final String path, FileInfo file) {
    TableRow tr = new TableRow(getActivity());
    tr.setLayoutParams(matchAndWrapTableRowLayout());

    tr.addView(widgetUtil.tableRowRightMargin(widgetUtil.createTextView(
        file.status != null ? Character.toString(file.status) : "M", 11), 4));

    TextView pathText = widgetUtil.createTextView(path, 11);
    pathText.setTextColor(widgetUtil.color(R.color.hyperlink));
    pathText.setPaintFlags(
        pathText.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
    pathText.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        display(UnifiedDiffFragment.create(path));
      }
    });
    tr.addView(widgetUtil.tableRowRightMargin(pathText, 4));

    tr.addView(widgetUtil.createTextView(
        FormatUtil.formatBytes(file.size), 11));

    // TODO show further file infos

    tl.addView(tr, matchAndWrapTableLayout());
  }

  @Override
  public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    ActionHandler actionHandler = getApp().getActionHandler();
    inflater.inflate(R.menu.menu_detailed_change, menu);
    for (int i = 0; i < menu.size(); i++) {
      MenuItem item = menu.getItem(i);
      if (item.getItemId() == R.id.action_abandon) {
        item.setVisible(actionHandler.hasCurrentChange()
            && (actionHandler.getCurrentChange().info.status
                  == ChangeStatus.NEW
              || actionHandler.getCurrentChange().info.status
                  == ChangeStatus.SUBMITTED));
      } else if (item.getItemId() == R.id.action_restore) {
        item.setVisible(actionHandler.hasCurrentChange()
            && actionHandler.getCurrentChange().info.status
                == ChangeStatus.ABANDONED);
      }
    }
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    ActionHandler actionHandler = getApp().getActionHandler();
    switch (item.getItemId()) {
      case R.id.action_add_reviewer:
        display(AddReviewerFragment.create(getClass()));
        return true;
      case R.id.action_abandon:
        display(AbandonFragment.create(getClass()));
        return true;
      case R.id.action_help:
        display(HelpFragment.class);
        return true;
      case R.id.action_ignore:
        actionHandler.ignore();
        startActivity(new Intent(getActivity(), MainActivity.class));
        return true;
      case R.id.action_restore:
        display(RestoreActivity.create(getClass()));
        return true;
      case R.id.action_skip:
        actionHandler.skip();
        startActivity(new Intent(getActivity(), MainActivity.class));
        return true;
      case R.id.action_star:
        actionHandler.star();
        startActivity(new Intent(getActivity(), MainActivity.class));
        return true;
      default:
        return super.onOptionsItemSelected(item);
    }
  }

  @Override
  public boolean onBackPressed() {
    display(SortChangesFragment.class);
    return true;
  }
}
