// 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>
    {foreach $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>
    {/foreach}
  </table>
</div>
{call .message_}
  {param className: 'u-pre u-monospace MetadataMessage' /}
  {param message: $message /}
{/call}

{if $diffTree and length($diffTree)}
  <ul class="DiffTree">
    {foreach $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>
    {/foreach}
  </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">
      {foreach $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>
      {/foreach}
    </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">
        {foreach $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}">
              {foreach $span in $line}
                <span class="{$span.classes}">{$span.text}</span>
              {/foreach}
            </td>
          </tr>
        {/foreach}
      </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}">
  {foreach $part in $message}
    {if $part.url}<a href="{$part.url}">{$part.text}</a>{else}{$part.text}{/if}
  {/foreach}
</pre>
{/template}
