// 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().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;
  }
}
