// 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.googlesource.gerrit.plugins.uploadvalidator;

import static com.google.common.truth.Truth.assertThat;
import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.EMPTY_PLUGIN_CONFIG;
import static com.googlesource.gerrit.plugins.uploadvalidator.TestUtils.PATTERN_CACHE;

import com.google.gerrit.server.git.validators.CommitValidationMessage;

import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ContentTypeValidatorTest extends ValidatorTestCase {

  private static final byte[] TEST_PDF = ("%PDF-1.4\n"
        + "1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >>\n"
        + "endobj 2 0 obj << /Type /Outlines /Count 0 >>\n"
        + "endobj 3 0 obj << /Type /Pages /Kids [4 0 R] /Count 1\n"
        + ">> endobj 4 0 obj << /Type /Page /Parent 3 0 R\n"
        + "/MediaBox [0 0 612 144] /Contents 5 0 R /Resources << /ProcSet 6 0 R\n"
        + "/Font << /F1 7 0 R >> >> >> endobj 5 0 obj\n"
        + "<< /Length 73 >> stream BT\n" + "/F1 24 Tf\n" + "100 100 Td\n"
        + "(Small pdf) Tj\n"
        + "ET endstream endobj 6 0 obj [/PDF /Text] endobj 7 0 obj\n"
        + "<< /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica\n"
        + "/Encoding /MacRomanEncoding >> endobj xref 0 8\n"
        + "0000000000 65535 f 0000000009 00000 n 0000000074 00000 n\n"
        + "0000000120 00000 n 0000000179 00000 n 0000000364 00000 n\n"
        + "0000000466 00000 n 0000000496 00000 n\n"
        + "trailer << /Size 8 /Root 1 0 R >> startxref 625\n" + "%%EOF")
        .getBytes(StandardCharsets.UTF_8);

  private ContentTypeValidator validator;

  @Before
  public void setUp() {
    validator = new ContentTypeValidator(
        null, new ContentTypeUtil(PATTERN_CACHE), null, null, null);
  }

  @Test
  public void testBlocked() throws Exception {
    String[] patterns =
        new String[] {"application/pdf", "application/xml", "text/html"};

    try (RevWalk rw = new RevWalk(repo)) {
      List<CommitValidationMessage> m = validator.performValidation(
          repo, makeCommit(rw), rw, patterns, false);
      assertThat(TestUtils.transformMessages(m)).containsExactly(
          "ERROR: found blocked content type (application/pdf) in file: foo.pdf",
          "ERROR: found blocked content type (application/xml) in file: foo.xml",
          "ERROR: found blocked content type (text/html) in file: foo.html");
    }
  }

  @Test
  public void testWhitelist() throws Exception {
    String[] patterns = new String[] {"application/pdf", "application/xml"};

    try (RevWalk rw = new RevWalk(repo)) {
      List<CommitValidationMessage> m = validator.performValidation(
          repo, makeCommit(rw), rw, patterns, true);
      assertThat(TestUtils.transformMessages(m)).containsExactly(
          "ERROR: found blocked content type (text/html) in file: foo.html");
    }
  }

  @Test
  public void validatorBehaviorWhenConfigEmpty() {
    assertThat(ContentTypeValidator.isActive(EMPTY_PLUGIN_CONFIG)).isFalse();
    assertThat(ContentTypeValidator.isWhitelist(EMPTY_PLUGIN_CONFIG)).isFalse();
  }

  private RevCommit makeCommit(RevWalk rw) throws IOException, GitAPIException {
    Map<File, byte[]> files = new HashMap<>();

    String content = "<?xml version=\"1.0\"?><a><b>c</b></a>";
    files.put(TestUtils.createEmptyFile("foo.xml", repo),
        content.getBytes(StandardCharsets.UTF_8));

    content = "<html><body><h1>Hello World!</h1></body></html>";
    files.put(TestUtils.createEmptyFile("foo.html", repo),
        content.getBytes(StandardCharsets.UTF_8));

    files.put(TestUtils.createEmptyFile("foo.pdf", repo), TEST_PDF);
    return TestUtils.makeCommit(rw, repo, "Commit with test files.", files);
  }
}
