// Copyright 2012 Google Inc. All Rights Reserved.
//
// 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.
{namespace gitiles}

/**
 * Detailed listing of a commit.
 *
 * @param author map with "name", "email", and "time" keys for the commit author.
 * @param committer map with "name", "email", and "time" keys for the committer.
 * @param sha commit SHA-1.
 * @param tree tree SHA-1.
 * @param treeUrl tree URL.
 * @param parents list of parent objects with the following keys:
 *     sha: SHA-1.
 *     url: URL to view the parent commit.
 *     diffUrl: URL to display diffs relative to this parent.
 *     blameUrl: optional URL to display blame of a file at this parent.
 * @param message list of commit message parts, where each part contains:
 *     text: raw text of the part.
 *     url: optional URL that should be linked to from the part.
 * @param diffTree list of changed tree entries with the following keys:
 *     changeType: string matching an org.eclipse.jgit.diff.DiffEntry.ChangeType
 *         constant.
 *     path: (new) path of the tree entry.
 *     oldPath: old path, only for renames and copies.
 *     url: URL to a detail page for the tree entry.
 *     diffUrl: URL to a diff page for the tree entry's diff in this commit.
 * @param logUrl URL to a log page starting at this commit.
 * @param archiveUrl URL to a download link of this commit as an archive.
 * @param archiveType type of the archive to download.
 */
{template .commitDetail}
<div class="u-monospace Metadata">
  <table>
    <tr>
      <th class="Metadata-title">{msg desc="Header for commit SHA entry"}commit{/msg}</th>
      <td>
        {$sha}
      </td>
      <td>
        <span>
          [<a href="{$logUrl}">{msg desc="text for the log link"}log{/msg}</a>]
        </span>
        {sp}<span>[<a href="{$archiveUrl}">{$archiveType}</a>]</span>
      </td>
    </tr>
    <tr>
      <th class="Metadata-title">{msg desc="Header for commit author"}author{/msg}</th>
      <td>{call .person_ data="$author" /}</td>
      <td>{$author.time}</td>
    </tr>
    <tr>
      <th class="Metadata-title">{msg desc="Header for committer"}committer{/msg}</th>
      <td>{call .person_ data="$committer" /}</td>
      <td>{$committer.time}</td>
    </tr>
    <tr>
      <th class="Metadata-title">{msg desc="Header for tree SHA entry"}tree{/msg}</th>
      <td><a href="{$treeUrl}">{$tree}</a></td>
    </tr>
    {for $parent in $parents}
      <tr>
        <th class="Metadata-title">{msg desc="Header for parent SHA"}parent{/msg}</th>
        <td>
          <a href="{$parent.url}">{$parent.sha}</a>
          {sp}<span>
            [<a href="{$parent.diffUrl}">{msg desc="text for the parent diff link"}diff{/msg}</a>]
            {if isNonnull($parent.blameUrl)}
              {sp}[<a href="{$parent.blameUrl}">{msg desc="text for the parent blame link"}blame{/msg}</a>]
            {/if}
          </span>
        </td>
      </tr>
    {/for}
  </table>
</div>
{call .message_}
  {param className: 'u-pre u-monospace MetadataMessage' /}
  {param message: $message /}
{/call}

{if $diffTree and length($diffTree)}
  <ul class="DiffTree">
    {for $entry in $diffTree}
      <li>
        <a href="{$entry.url}">{$entry.path}</a>
        {switch $entry.changeType}
          {case 'ADD'}
            <span class="DiffTree-action DiffTree-action--add">
              {msg desc="Text for a new tree entry"}
                [Added - <a href="{$entry.diffUrl}">diff</a>]
              {/msg}
            </span>
          {case 'MODIFY'}
            <span class="DiffTree-action DiffTree-action--modify">
              {msg desc="Text for a modified tree entry"}
                [<a href="{$entry.diffUrl}">diff</a>]
              {/msg}
            </span>
          {case 'DELETE'}
            <span class="DiffTree-action DiffTree-action--delete">
              {msg desc="Text for a deleted tree entry"}
                [Deleted - <a href="{$entry.diffUrl}">diff</a>]
              {/msg}
            </span>
          {case 'RENAME'}
            <span class="DiffTree-action DiffTree-action--rename">
              {msg desc="Text for a renamed tree entry"}
                [Renamed from {$entry.oldPath} - <a href="{$entry.diffUrl}">diff</a>]
              {/msg}
            </span>
          {case 'COPY'}
            <span class="DiffTree-action DiffTree-action--copy">
              {msg desc="Text for a copied tree entry"}
                [Copied from {$entry.oldPath} - <a href="{$entry.diffUrl}">diff</a>]
              {/msg}
            </span>
          {default}
        {/switch}
      </li>
    {/for}
  </ul>
  <div class="DiffSummary">
    {if length($diffTree) == 1}
      {msg desc="1 file changed"}1 file changed{/msg}
    {else}
      {msg desc="number of files changed"}{length($diffTree)} files changed{/msg}
    {/if}
  </div>
{/if}

{/template}

/**
 * Detailed listing of a tree.
 *
 * @param sha SHA of this path's tree.
 * @param? logUrl optional URL to a log for this path.
 * @param? archiveUrl optional URL to a download link of this tree as an archive.
 * @param? archiveType type of the archive to download, if archiveUrl is set.
 * @param entries list of entries with the following keys:
 *     type: entry type, matching one of the constant names defined in
 *         org.eclipse.jgit.lib.FileMode.
 *     name: tree entry name.
 *     url: URL to link to.
 *     targetName: name of a symlink target, required only if type == 'SYMLINK'.
 *     targetUrl: optional url of a symlink target, required only if
 *         type == 'SYMLINK'.
 * @param? readmePath optional path of the selected README.md file.
 * @param? readmeHtml optional rendered README.md contents.
 */
{template .treeDetail}
<div class="TreeDetail">
  <div class="u-sha1 u-monospace TreeDetail-sha1">
    {msg desc="SHA-1 for the path's tree"}tree: {$sha}{/msg}
    {if $logUrl}{sp}[<a href="{$logUrl}">{msg desc="history for a path"}path history{/msg}</a>]{/if}
    {if $archiveUrl}
      {sp}<span>[<a href="{$archiveUrl}">{$archiveType}</a>]</span>
    {/if}
  </div>

  {if length($entries)}
    <ol class="FileList">
      {for $entry in $entries}
        <li class="FileList-item{sp}
              {switch $entry.type}
                {case 'TREE'}FileList-item--gitTree
                {case 'SYMLINK'}FileList-item--symlink
                {case 'REGULAR_FILE'}FileList-item--regularFile
                {case 'EXECUTABLE_FILE'}FileList-item--executableFile
                {case 'GITLINK'}gitlink
                {default}regular-file
              {/switch}
              " title="
              {switch $entry.type}
                {case 'TREE'}{msg desc="Alt text for tree icon"}Tree{/msg}
                {case 'SYMLINK'}{msg desc="Alt text for symlink icon"}Symlink{/msg}
                {case 'REGULAR_FILE'}{msg desc="Alt text for regular file icon"}Regular file{/msg}
                {case 'EXECUTABLE_FILE'}
                  {msg desc="Alt text for executable file icon"}Executable file{/msg}
                {case 'GITLINK'}
                  {msg desc="Alt text for git submodule link icon"}Git submodule link{/msg}
                {default}{msg desc="Alt text for other file icon"}Other{/msg}
              {/switch}
              {sp}- {$entry.name}">
          <a class="FileList-itemLink" href="{$entry.url}">{$entry.name}</a>
          {if $entry.type == 'SYMLINK'}
            {sp}&#x21e8;{sp}
            {if $entry.targetUrl}
              <a href="{$entry.targetUrl}">{$entry.targetName}</a>
            {else}
              {$entry.targetName}
            {/if}
          {/if}
          // TODO(dborowitz): Something reasonable for gitlinks.
        </li>
      {/for}
    </ol>
  {else}
    <p>{msg desc="Informational text for when a tree is empty"}This tree is empty.{/msg}</p>
  {/if}

  {if $readmeHtml}
    <div class="InlineReadme">
      <div class="InlineReadme-path">{$readmePath}</div>
      <div class="doc">{$readmeHtml}</div>
    </div>
  {/if}
</div>
{/template}

/**
 * Common header for a blob shared between detail, blame, etc. views.
 *
 * @param sha SHA of this file's blob.
 * @param? fileUrl optional URL to a detail view of this file.
 * @param? logUrl optional URL to a log for this file.
 * @param? blameUrl optional URL to a blame for this file.
 * @param? docUrl optional URL to view rendered file.
 */
{template .blobHeader}
<div class="u-sha1 u-monospace BlobSha1">
  {msg desc="SHA-1 for the file's blob"}blob: {$sha}{/msg}
  {if $fileUrl}{sp}[<a href="{$fileUrl}">{msg desc="detail view of a file"}file{/msg}</a>]{/if}
  {if $logUrl}{sp}[<a href="{$logUrl}">{msg desc="history for a file"}log{/msg}</a>]{/if}
  {if $blameUrl}{sp}[<a href="{$blameUrl}">{msg desc="blame for a file"}blame{/msg}</a>]{/if}
  {if $docUrl}{sp}[<a href="{$docUrl}">{msg desc="view rendered file"}view{/msg}</a>]{/if}
</div>
{/template}

/**
 * Detailed listing of a blob.
 *
 * @param sha SHA of this file's blob.
 * @param? logUrl optional URL to a log for this file.
 * @param? blameUrl optional URL to a blame for this file.
 * @param lines lines (may be empty), or null for a binary file. Each line
 *     is a list of entries with "classes" and "text" fields for pretty-printed
 *     spans.
 * @param? size for binary files only, size in bytes.
 */
{template .blobDetail}
  {call .blobHeader data="all" /}

  {if $lines != null}
    {if $lines}
      <table class="FileContents">
        {for $line in $lines}
          {let $n: index($line) + 1 /}
          <tr class="u-pre u-monospace FileContents-line">
            <td class="u-lineNum u-noSelect FileContents-lineNum"
                data-line-number="{$n}" onclick="window.location.hash='#{$n}'"></td>
            <td class="FileContents-lineContents" id="{$n}">
              {for $span in $line}
                <span class="{$span.classes}">{$span.text}</span>
              {/for}
            </td>
          </tr>
        {/for}
      </table>
    {else}
      <div class="FileContents-empty">Empty file</div>
    {/if}
  {else}
    <div class="FileContents-binary">
      {msg desc="size of binary file in bytes"}{$size}-byte binary file{/msg}
    </div>
  {/if}
{/template}

/**
 * Detailed listing of an annotated tag.
 *
 * @param sha SHA of this tag.
 * @param? tagger optional map with "name", "email", and "time" keys for the
 *     tagger.
 * @param object SHA of the object this tag points to.
 * @param message tag message.
 */
{template .tagDetail}
<div class="u-monospace Metadata">
  <table>
    <tr>
      <th class="Metadata-title">{msg desc="Header for tag SHA entry"}tag{/msg}</th>
      <td class="sha">{$sha}</td>
      <td>{sp}</td>
    </tr>
    {if $tagger}
      <tr>
        <th class="Metadata-title">{msg desc="Header for tagger"}tagger{/msg}</th>
        <td>{call .person_ data="$tagger" /}</td>
        <td>{$tagger.time}</td>
      </tr>
    {/if}
    <tr>
      <th class="Metadata-title">{msg desc="Header for tagged object SHA"}object{/msg}</th>
      <td class="sha">{$object}</td>
      <td>{sp}</td>
    </tr>
  </table>
</div>
{if $message and length($message)}
  {call .message_}
    {param className: 'u-pre u-monospace MetadataMessage' /}
    {param message: $message /}
  {/call}
{/if}
{/template}

/**
 * Line about a git person identity.
 *
 * @param name name.
 * @param email email.
 */
{template .person_}
{$name}{if $email} &lt;{$email}&gt;{/if}
{/template}

/**
 * Preformatted message, possibly containing hyperlinks.
 *
 * @param className CSS class name for <pre> block.
 * @param message list of message parts, where each part contains:
 *     text: raw text of the part.
 *     url: optional URL that should be linked to from the part.
 */
{template .message_ visibility="private"}
<pre class="{$className}">
  {for $part in $message}
    {if $part.url}<a href="{$part.url}">{$part.text}</a>{else}{$part.text}{/if}
  {/for}
</pre>
{/template}
