// 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.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ProgressBar;

import com.google.gerrit.extensions.common.DiffInfo;
import com.google.gerrit.extensions.common.FileInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.reviewit.app.Change;
import com.google.reviewit.util.FormatUtil;
import com.google.reviewit.util.LayoutUtil;
import com.google.reviewit.util.WidgetUtil;
import com.google.reviewit.widget.PostReviewView;
import com.google.reviewit.widget.ScrollWithHeadingsView;
import com.google.reviewit.widget.UnifiedDiffView;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import static com.google.common.base.Preconditions.checkState;
import static com.google.reviewit.util.LayoutUtil.matchLayout;
import static com.google.reviewit.util.WidgetUtil.setGone;
import static com.google.reviewit.util.WidgetUtil.setInvisible;
import static com.google.reviewit.util.WidgetUtil.setVisible;

/**
 * Fragment that shows a list of unified diffs for all files of one change.
 */
public class UnifiedDiffFragment extends BaseFragment
    implements OnBackPressedAware, DispatchTouchEventAware {
  private static final String TAG = UnifiedDiffFragment.class.getName();
  private static final String PATH =
      "com.google.reviewit.UnifiedDiffFragment.PATH";

  private ScrollWithHeadingsView root;

  public static UnifiedDiffFragment create(String path) {
    UnifiedDiffFragment fragment = new UnifiedDiffFragment();
    Bundle bundle = new Bundle();
    bundle.putString(PATH, path);
    fragment.setArguments(bundle);
    return fragment;
  }

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

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

    ((MainActivity) getActivity()).getSupportActionBar().hide();

    String path = getArguments() != null
        ? getArguments().getString(PATH)
        : null;

    Change change = getApp().getSortActionHandler().getCurrentChange();
    checkState(change != null, "Change not set");
    Map<String, FileInfo> files = change.currentRevision().files;
    root = (ScrollWithHeadingsView) v(R.id.unifiedDiffRoot);
    root.setWindow(getWindow());

    if (path != null) {
      setVisible(v(R.id.navigationButtons));
      initPostReviewNavPanel(change);
      FileInfo file = files.get(path);
      checkState(file != null, "File not found:" + path);
      init(root, path, change, files);
      displayFile(root, change, path, file);
    } else {
      setGone(v(R.id.navigationButtons));
      initPostReviewPanel(change);
      displayFiles(root, change, files);
    }
  }

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

  private void initPostReviewPanel(Change change) {
    initPostReview(change, R.id.postReview);

    setVisible(v(R.id.postReviewPanel));

    v(R.id.expandPostReviewPanel).setOnClickListener(
        new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        setGone(v(R.id.expandPostReviewPanel));
        setVisible(v(R.id.collapsePostReviewPanel, R.id.postReview));
      }
    });

    v(R.id.collapsePostReviewPanel).setOnClickListener(
        new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        setGone(v(R.id.collapsePostReviewPanel, R.id.postReview));
        setVisible(v(R.id.expandPostReviewPanel));
      }
    });
  }

  private void initPostReviewNavPanel(Change change) {
    initPostReview(change, R.id.postReviewNav);

    v(R.id.expandPostReviewPanelNav).setOnClickListener(
        new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        setGone(v(R.id.expandPostReviewPanelNav));
        setVisible(v(R.id.collapsePostReviewPanelNav, R.id.postReviewNav));
      }
    });

    v(R.id.collapsePostReviewPanelNav).setOnClickListener(
        new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        setGone(v(R.id.collapsePostReviewPanelNav, R.id.postReviewNav));
        setVisible(v(R.id.expandPostReviewPanelNav));
      }
    });
  }

  private void initPostReview(Change change, @IdRes int id) {
    PostReviewView postReview = ((PostReviewView) v(id));
    postReview.setChange(change);
    postReview.select(change.getVote("Code-Review", getApp().getSelf()));
    postReview.setOnVoteListener(new PostReviewView.OnVoteListener() {
      @Override
      public void vote(int vote) {
        display(PostReviewFragment.create(vote));
      }
    });
  }

  private void init(ScrollWithHeadingsView root, String path, Change change,
                    Map<String, FileInfo> files) {
    String prevPath = null;
    String nextPath = null;
    List<String> paths = new ArrayList<>(files.keySet());
    int i = paths.indexOf(path);
    if (i > 0) {
      prevPath = paths.get(i - 1);
    }
    if (i < paths.size() - 1) {
      nextPath = paths.get(i + 1);
    }
    root.setNextBackgroundColor(i);

    if (prevPath != null || nextPath != null) {
      if (prevPath != null) {
        setVisible(v(R.id.navigationPrev));
        WidgetUtil.setText(v(R.id.navigationPrevFile),
            new File(prevPath).getName());
        setNavigationOnClickListener(R.id.navigationPrev, root, change,
            prevPath, files);
      } else {
        setInvisible(v(R.id.navigationPrev));
      }
      if (nextPath != null) {
        setVisible(v(R.id.navigationNext));
        WidgetUtil.setText(v(R.id.navigationNextFile),
            new File(nextPath).getName());
        setNavigationOnClickListener(R.id.navigationNext, root, change,
            nextPath, files);
      } else {
        setInvisible(v(R.id.navigationNext));
      }
    }
  }

  private void setNavigationOnClickListener(
      @IdRes int id, final ScrollWithHeadingsView root, final Change change,
      final String path, final Map<String, FileInfo> files) {
    v(id).setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        root.clear();
        init(root, path, change, files);
        displayFile(root, change, path, files.get(path));
      }
    });
  }

  private void displayFile(
      ScrollWithHeadingsView root, Change change, String path, FileInfo file) {
    Map<String, FileInfo> files = new HashMap<>();
    files.put(path, file);
    displayFiles(root, change, files);
  }

  private void displayFiles(
      final ScrollWithHeadingsView root, final Change change,
      Map<String, FileInfo> files) {
    final Iterator<Map.Entry<String, FileInfo>> fileEntryIt =
        files.entrySet().iterator();
    root.setContent(new Iterator<ScrollWithHeadingsView.Content>() {
      @Override
      public boolean hasNext() {
        return fileEntryIt.hasNext();
      }

      @Override
      public ScrollWithHeadingsView.Content next() {
        Map.Entry<String, FileInfo> fileEntry = fileEntryIt.next();
        File f = new File(fileEntry.getKey());
        return new ScrollWithHeadingsView.Content(
            new ScrollWithHeadingsView.HeadingWithDetails(
                getContext(), f.getName(), null,
                FormatUtil.ensureSlash(f.getParent())),
                createContent(change, fileEntry.getKey(),
                    fileEntry.getValue()));
      }

      public View createContent(
          final Change change, final String path, FileInfo file) {
        final LinearLayout layout = new LinearLayout(getContext());
        layout.setLayoutParams(new ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, widgetUtil.dpToPx(400)));
        layout.setPadding(0, widgetUtil.dpToPx(30), 0, widgetUtil.dpToPx(30));
        layout.setGravity(Gravity.CENTER_HORIZONTAL);
        final ProgressBar p = new ProgressBar(getContext());
        p.setLayoutParams(matchLayout());
        p.setIndeterminate(true);
        p.getIndeterminateDrawable().setColorFilter(
            widgetUtil.color(R.color.progressReload),
            android.graphics.PorterDuff.Mode.SRC_IN);
        layout.addView(p);

        if (file.binary != null && file.binary) {
          // TODO
          return layout;
        }

        LayoutUtil.addOneTimeOnGlobalLayoutListener(
            p, new LayoutUtil.OneTimeOnGlobalLayoutListener() {
          @Override
          public void onFirstGlobalLayout() {
            new AsyncTask<String, Void, DiffInfo>() {
              @Override
              protected DiffInfo doInBackground(String... paths) {
                String path = paths[0];
                try {
                  return change.diff(path);
                } catch (RestApiException e) {
                  Log.e(TAG, "Failed to get diff of file " + path
                      + " from change " + change.info._number, e);
                  return null;
                }
              }

              protected void onPostExecute(final DiffInfo diff) {
                layout.removeView(p);
                layout.setLayoutParams(
                    new LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.MATCH_PARENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT));
                layout.setPadding(0,
                    layout.getPaddingTop() - widgetUtil.dpToPx(20),
                    0,
                    layout.getPaddingBottom() - widgetUtil.dpToPx(20));
                UnifiedDiffView unifiedDiffView = new UnifiedDiffView
                    (getContext(), diff);
                layout.addView(unifiedDiffView);
                LayoutUtil.addOneTimeOnGlobalLayoutListener(
                    unifiedDiffView,
                    new LayoutUtil.OneTimeOnGlobalLayoutListener() {
                      @Override
                      public void onFirstGlobalLayout() {
                        root.relayout();
                      }
                    });
                unifiedDiffView.setOnSizeChangedListener(
                    new UnifiedDiffView.OnSizeChangedListener() {
                  @Override
                  public void onSizeChanged() {
                    root.relayout();
                  }
                });
              }
            }.executeOnExecutor(getApp().getExecutor(), path);
          }
        });

        return layout;
      }

      @Override
      public void remove() {
        throw new UnsupportedOperationException();
      }
    });
  }

  @Override
  public boolean onBackPressed() {
    // TODO abort background tasks
    return false;
  }
}
