import * as React from 'react';
import { Link } from 'react-router-dom';
import { map } from 'rxjs/operators';
import { replaceRevisionInURL } from '.';
import { gql, queryGraphQL } from '../backend/graphql';
import { FilteredConnection } from '../components/FilteredConnection';
import { TabsWithLocalStorageViewStatePersistence } from '../components/Tabs';
import { eventLogger } from '../tracking/eventLogger';
import { createAggregateError } from '../util/errors';
import { CircleChevronLeftIcon } from '../util/icons'; // TODO: Switch to mdi icon
import { memoizeObservable } from '../util/memoize';
import { GitRefNode, queryGitRefs } from './GitRef';
const fetchRepositoryCommits = memoizeObservable((args) => queryGraphQL(gql `
                query RepositoryGitCommit($repo: ID!, $first: Int, $rev: String!, $query: String) {
                    node(id: $repo) {
                        ... on Repository {
                            commit(rev: $rev) {
                                ancestors(first: $first, query: $query) {
                                    nodes {
                                        id
                                        oid
                                        abbreviatedOID
                                        author {
                                            person {
                                                name
                                                avatarURL
                                            }
                                            date
                                        }
                                        subject
                                    }
                                    pageInfo {
                                        hasNextPage
                                    }
                                }
                            }
                        }
                    }
                }
            `, args).pipe(map(({ data, errors }) => {
    if (!data ||
        !data.node ||
        !data.node.commit ||
        !data.node.commit.ancestors) {
        throw createAggregateError(errors);
    }
    return data.node.commit.ancestors;
})), x => JSON.stringify(x));
const GitRefPopoverNode = ({ node, defaultBranch, currentRev, location }) => {
    let isCurrent;
    if (currentRev) {
        isCurrent = node.name === currentRev || node.abbrevName === currentRev;
    }
    else {
        isCurrent = node.name === `refs/heads/${defaultBranch}`;
    }
    return (React.createElement(GitRefNode, { node: node, url: replaceRevisionInURL(location.pathname + location.search + location.hash, node.abbrevName), rootIsLink: true }, isCurrent && (React.createElement(CircleChevronLeftIcon, { className: "icon-inline connection-popover__node-link-icon", "data-tooltip": "Current" }))));
};
const GitCommitNode = ({ node, currentCommitID, location }) => {
    const isCurrent = currentCommitID === node.oid;
    return (React.createElement("li", { key: node.oid, className: "connection-popover__node revisions-popover-git-commit-node" },
        React.createElement(Link, { to: replaceRevisionInURL(location.pathname + location.search + location.hash, node.oid), className: `connection-popover__node-link ${isCurrent ? 'connection-popover__node-link--active' : ''} revisions-popover-git-commit-node__link` },
            React.createElement("code", { className: "revisions-popover-git-commit-node__oid", title: node.oid }, node.abbreviatedOID),
            React.createElement("span", { className: "revisions-popover-git-commit-node__message" }, (node.subject || '').slice(0, 200)),
            isCurrent && (React.createElement(CircleChevronLeftIcon, { className: "icon-inline connection-popover__node-link-icon", "data-tooltip": "Current commit" })))));
};
class FilteredGitRefConnection extends FilteredConnection {
}
class FilteredGitCommitConnection extends FilteredConnection {
}
/**
 * A popover that displays a searchable list of revisions (grouped by type) for
 * the current repository.
 */
export class RevisionsPopover extends React.PureComponent {
    constructor() {
        super(...arguments);
        this.queryGitBranches = (args) => queryGitRefs(Object.assign({}, args, { repo: this.props.repo, type: "GIT_BRANCH" /* GIT_BRANCH */, withBehindAhead: false }));
        this.queryGitTags = (args) => queryGitRefs(Object.assign({}, args, { repo: this.props.repo, type: "GIT_TAG" /* GIT_TAG */, withBehindAhead: false }));
        this.queryRepositoryCommits = (args) => fetchRepositoryCommits(Object.assign({}, args, { repo: this.props.repo, rev: this.props.currentRev || this.props.defaultBranch }));
    }
    componentDidMount() {
        eventLogger.logViewEvent('RevisionsPopover');
    }
    render() {
        return (React.createElement("div", { className: "revisions-popover connection-popover" },
            React.createElement(TabsWithLocalStorageViewStatePersistence, { tabs: RevisionsPopover.TABS, storageKey: RevisionsPopover.LAST_TAB_STORAGE_KEY, className: "revisions-popover__tabs" }, RevisionsPopover.TABS.map((tab, i) => tab.type ? (React.createElement(FilteredGitRefConnection, { key: tab.id, className: "connection-popover__content", showMoreClassName: "connection-popover__show-more", compact: true, noun: tab.noun, pluralNoun: tab.pluralNoun, queryConnection: tab.type === "GIT_BRANCH" /* GIT_BRANCH */
                    ? this.queryGitBranches
                    : this.queryGitTags, nodeComponent: GitRefPopoverNode, nodeComponentProps: {
                    defaultBranch: this.props.defaultBranch,
                    currentRev: this.props.currentRev,
                    location: this.props.location,
                }, defaultFirst: 50, autoFocus: true, noSummaryIfAllNodesVisible: true, shouldUpdateURLQuery: false, history: this.props.history, location: this.props.location })) : (React.createElement(FilteredGitCommitConnection, { key: tab.id, className: "connection-popover__content", compact: true, noun: tab.noun, pluralNoun: tab.pluralNoun, queryConnection: this.queryRepositoryCommits, nodeComponent: GitCommitNode, nodeComponentProps: {
                    currentCommitID: this.props.currentCommitID,
                    location: this.props.location,
                }, defaultFirst: 15, autoFocus: true, history: this.props.history, location: this.props.location, noSummaryIfAllNodesVisible: true, shouldUpdateURLQuery: false }))))));
    }
}
RevisionsPopover.LAST_TAB_STORAGE_KEY = 'RevisionsPopover.lastTab';
RevisionsPopover.TABS = [
    { id: 'branches', label: 'Branches', noun: 'branch', pluralNoun: 'branches', type: "GIT_BRANCH" /* GIT_BRANCH */ },
    { id: 'tags', label: 'Tags', noun: 'tag', pluralNoun: 'tags', type: "GIT_TAG" /* GIT_TAG */ },
    { id: 'commits', label: 'Commits', noun: 'commit', pluralNoun: 'commits' },
];
//# sourceMappingURL=RevisionsPopover.js.map