// Copyright (C) 2014 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.gerrit.reviewdb.client;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import org.junit.Test;

public class ChangeTest {
  @Test
  public void parseInvalidRefNames() {
    assertNotRef(null);
    assertNotRef("");
    assertNotRef("01/1/1");
    assertNotRef("HEAD");
    assertNotRef("refs/tags/v1");
  }

  @Test
  public void parsePatchSetRefNames() {
    assertRef(1, "refs/changes/01/1/1");
    assertRef(1234, "refs/changes/34/1234/56");

    // Invalid characters.
    assertNotRef("refs/changes/0x/1/1");
    assertNotRef("refs/changes/01/x/1");
    assertNotRef("refs/changes/01/1/x");

    // Truncations.
    assertNotRef("refs/changes/");
    assertNotRef("refs/changes/1");
    assertNotRef("refs/changes/01");
    assertNotRef("refs/changes/01/");
    assertNotRef("refs/changes/01/1/");
    assertNotRef("refs/changes/01/1/1/");
    assertNotRef("refs/changes/01//1/1");

    // Leading zeroes.
    assertNotRef("refs/changes/01/01/1");
    assertNotRef("refs/changes/01/1/01");

    // Mismatched last 2 digits.
    assertNotRef("refs/changes/35/1234/56");

    // Something other than patch set after change.
    assertNotRef("refs/changes/34/1234/0");
    assertNotRef("refs/changes/34/1234/foo");
    assertNotRef("refs/changes/34/1234|56");
    assertNotRef("refs/changes/34/1234foo");
  }

  @Test
  public void parseEditRefNames() {
    assertRef(5, "refs/users/34/1234/edit-5/1");
    assertRef(5, "refs/users/34/1234/edit-5");
    assertNotRef("refs/changes/34/1234/edit-5/1");
    assertNotRef("refs/users/34/1234/EDIT-5/1");
    assertNotRef("refs/users/34/1234");
  }

  @Test
  public void parseChangeMetaRefNames() {
    assertRef(1, "refs/changes/01/1/meta");
    assertRef(1234, "refs/changes/34/1234/meta");

    assertNotRef("refs/changes/01/1/met");
    assertNotRef("refs/changes/01/1/META");
    assertNotRef("refs/changes/01/1/1/meta");
  }

  @Test
  public void parseRobotCommentRefNames() {
    assertRef(1, "refs/changes/01/1/robot-comments");
    assertRef(1234, "refs/changes/34/1234/robot-comments");

    assertNotRef("refs/changes/01/1/robot-comment");
    assertNotRef("refs/changes/01/1/ROBOT-COMMENTS");
    assertNotRef("refs/changes/01/1/1/robot-comments");
  }

  @Test
  public void parseStarredChangesRefNames() {
    assertAllUsersRef(1, "refs/starred-changes/01/1/1001");
    assertAllUsersRef(1234, "refs/starred-changes/34/1234/1001");

    assertNotRef("refs/starred-changes/01/1/1001");
    assertNotAllUsersRef(null);
    assertNotAllUsersRef("refs/starred-changes/01/1/1xx1");
    assertNotAllUsersRef("refs/starred-changes/01/1/");
    assertNotAllUsersRef("refs/starred-changes/01/1");
    assertNotAllUsersRef("refs/starred-changes/35/1234/1001");
    assertNotAllUsersRef("refs/starred-changeS/01/1/1001");
  }

  @Test
  public void parseDraftRefNames() {
    assertAllUsersRef(1, "refs/draft-comments/01/1/1001");
    assertAllUsersRef(1234, "refs/draft-comments/34/1234/1001");

    assertNotRef("refs/draft-comments/01/1/1001");
    assertNotAllUsersRef(null);
    assertNotAllUsersRef("refs/draft-comments/01/1/1xx1");
    assertNotAllUsersRef("refs/draft-comments/01/1/");
    assertNotAllUsersRef("refs/draft-comments/01/1");
    assertNotAllUsersRef("refs/draft-comments/35/1234/1001");
    assertNotAllUsersRef("refs/draft-commentS/01/1/1001");
  }

  @Test
  public void toRefPrefix() {
    assertThat(new Change.Id(1).toRefPrefix()).isEqualTo("refs/changes/01/1/");
    assertThat(new Change.Id(1234).toRefPrefix()).isEqualTo("refs/changes/34/1234/");
  }

  @Test
  public void parseRefNameParts() {
    assertRefPart(1, "01/1");

    assertNotRefPart(null);
    assertNotRefPart("");

    // This method assumes that the common prefix "refs/changes/" was removed.
    assertNotRefPart("refs/changes/01/1");

    // Invalid characters.
    assertNotRefPart("01a/1");
    assertNotRefPart("01/a1");

    // Mismatched shard.
    assertNotRefPart("01/23");

    // Shard too short.
    assertNotRefPart("1/1");
  }

  private static void assertRef(int changeId, String refName) {
    assertThat(Change.Id.fromRef(refName)).isEqualTo(new Change.Id(changeId));
  }

  private static void assertNotRef(String refName) {
    assertThat(Change.Id.fromRef(refName)).isNull();
  }

  private static void assertAllUsersRef(int changeId, String refName) {
    assertThat(Change.Id.fromAllUsersRef(refName)).isEqualTo(new Change.Id(changeId));
  }

  private static void assertNotAllUsersRef(String refName) {
    assertThat(Change.Id.fromAllUsersRef(refName)).isNull();
  }

  private static void assertRefPart(int changeId, String refName) {
    assertEquals(new Change.Id(changeId), Change.Id.fromRefPart(refName));
  }

  private static void assertNotRefPart(String refName) {
    assertNull(Change.Id.fromRefPart(refName));
  }
}
