// Copyright (C) 2019 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.copyright.lib;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableList;
import com.google.common.truth.Correspondence;
import com.googlesource.gerrit.plugins.copyright.lib.CopyrightPatterns.RuleSet;
import com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.Match;
import com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.MatchType;
import com.googlesource.gerrit.plugins.copyright.lib.CopyrightScanner.PartyType;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class CopyrightScannerTest {

  private static final Correspondence<String, String> CONTAINS_STRING =
      Correspondence.from((actual, expected) -> actual.contains(expected), "contains");

  private CopyrightPatterns.RuleSet.Builder builder;

  @Before
  public void setUp() {
    builder =
        CopyrightPatterns.RuleSet.builder()
            .exclude("EXAMPLES")
            .addFirstParty("APACHE2")
            .addFirstParty("ANDROID")
            .addForbidden("NOT_A_CONTRIBUTION");
  }

  @Test
  public void tesFindMatch_firstPartyLicense() throws Exception {
    CopyrightScanner scanner = newScanner();
    ImmutableList<Match> actual =
        scanner.findMatches(
            "header.h",
            -1,
            readerFromString(
                "/*\n * License: apache2\n */\n#ifndef HEADER_H\n#define HEADER_H\n#end\n"));
    assertThat(actual.stream().map(m -> m.matchType).collect(Collectors.toList()))
        .containsExactly(MatchType.LICENSE);
    assertThat(actual.stream().map(m -> m.partyType).collect(Collectors.toList()))
        .containsExactly(PartyType.FIRST_PARTY);
    assertThat(actual.stream().map(m -> m.text).collect(Collectors.toList()))
        .comparingElementsUsing(CONTAINS_STRING)
        .containsExactly("apache2");
  }

  @Test
  public void tesFindMatch_firstPartyOwner() throws Exception {
    CopyrightScanner scanner = newScanner();
    ImmutableList<Match> actual =
        scanner.findMatches(
            "Class.java",
            -1,
            readerFromString(
                "/*\n * Copyright (C) 2019 Android Open Source Project\n"
                    + " */\npublic class Class {}\n"));
    assertThat(actual.stream().map(m -> m.matchType).collect(Collectors.toList()))
        .containsExactly(MatchType.AUTHOR_OWNER);
    assertThat(actual.stream().map(m -> m.partyType).collect(Collectors.toList()))
        .containsExactly(PartyType.FIRST_PARTY);
    assertThat(actual.stream().map(m -> m.text).collect(Collectors.toList()))
        .comparingElementsUsing(CONTAINS_STRING)
        .containsExactly("Android Open Source Project");
  }

  @Test
  public void tesFindMatch_thirdPartyLicense() throws Exception {
    builder.addThirdParty("BSD");
    CopyrightScanner scanner = newScanner();
    ImmutableList<Match> actual =
        scanner.findMatches(
            "script.sh",
            -1,
            readerFromString("#!/bin/sh\n# SPDX-License-Identifier: BSD-2-Clause\nexit 0\n"));
    assertThat(actual.stream().map(m -> m.matchType).collect(Collectors.toList()))
        .containsExactly(MatchType.LICENSE);
    assertThat(actual.stream().map(m -> m.partyType).collect(Collectors.toList()))
        .containsExactly(PartyType.THIRD_PARTY);
  }

  @Test
  public void tesFindMatch_thirdPartyOwner() throws Exception {
    CopyrightScanner scanner = newScanner();
    ImmutableList<Match> actual =
        scanner.findMatches(
            "Class.java",
            -1,
            readerFromString(
                "/*\n * Copyright (C) 2019 Sarah W. Eng <swe@example.com>\n"
                    + " */\npublic class Class {}\n"));
    assertThat(actual.stream().map(m -> m.matchType).collect(Collectors.toList()))
        .containsExactly(MatchType.AUTHOR_OWNER);
    assertThat(actual.stream().map(m -> m.partyType).collect(Collectors.toList()))
        .containsExactly(PartyType.THIRD_PARTY);
  }

  @Test
  public void tesFindMatch_forbiddenLicense() throws Exception {
    CopyrightScanner scanner = newScanner();
    ImmutableList<Match> actual =
        scanner.findMatches(
            "script.sh", -1, readerFromString("#!/bin/sh\n# Not a contribution.\nexit 0\n"));
    assertThat(actual.stream().map(m -> m.matchType).collect(Collectors.toList()))
        .containsExactly(MatchType.LICENSE);
    assertThat(actual.stream().map(m -> m.partyType).collect(Collectors.toList()))
        .containsExactly(PartyType.FORBIDDEN);
  }

  @Test
  public void tesFindMatch_forbiddenOwner() throws Exception {
    builder.addForbidden("GOOGLE");
    CopyrightScanner scanner = newScanner();
    ImmutableList<Match> actual =
        scanner.findMatches(
            "Class.java",
            -1,
            readerFromString(
                "/*\n * Copyright (C) 2019 Google Inc.\n" + " */\npublic class Class {}\n"));
    assertThat(actual.stream().map(m -> m.matchType).collect(Collectors.toList()))
        .containsExactly(MatchType.AUTHOR_OWNER);
    assertThat(actual.stream().map(m -> m.partyType).collect(Collectors.toList()))
        .containsExactly(PartyType.FORBIDDEN);
  }

  @Test
  public void testFindMatch_unknownLicense() throws Exception {
    CopyrightScanner scanner = newScanner();
    ImmutableList<Match> actual =
        scanner.findMatches(
            "Class.java",
            -1,
            readerFromString(
                "/*\n * Licensed in the jurisdiction of New York.\n"
                    + " */\npublic class Class {}\n"));
    assertThat(actual.stream().map(m -> m.matchType).collect(Collectors.toList()))
        .containsExactly(MatchType.LICENSE);
    assertThat(actual.stream().map(m -> m.partyType).collect(Collectors.toList()))
        .containsExactly(PartyType.UNKNOWN);
    assertThat(actual.stream().map(m -> m.text).collect(Collectors.toList()))
        .containsExactly("Licensed...jurisdiction");
  }

  @Test
  public void tesFindMatch_exclusion() throws Exception {
    builder.excludePattern("apache2");
    CopyrightScanner scanner = newScanner();
    ImmutableList<Match> foundMatches =
        scanner.findMatches(
            "header.h",
            -1,
            readerFromString(
                "/*\n * License: apache2\n */\n#ifndef HEADER_H\n#define HEADER_H\n#end\n"));
    assertThat(foundMatches).isEmpty();
  }

  @Test
  public void tesFindMatch_largeFileNoMatches() throws Exception {
    Stopwatch sw = Stopwatch.createUnstarted();
    CopyrightScanner scanner = newScanner();
    IndexedLineReader file = largeFile("");
    sw.start();
    ImmutableList<Match> foundMatches = scanner.findMatches("header.h", -1, file);
    sw.stop();
    assertThat(foundMatches).isEmpty();
    // Fail if protections against excessive backtracking seem to fail.
    assertThat(sw.elapsed().getSeconds()).isLessThan(8L); // normally 1s
  }

  @Test
  public void tesFindMatch_largeFileWithMatch() throws Exception {
    Stopwatch sw = Stopwatch.createUnstarted();
    builder.addThirdParty("BSD");
    CopyrightScanner scanner = newScanner();
    IndexedLineReader file = largeFile("# SPDX-License-Identifier: BSD-3-Clause\n");
    sw.start();
    ImmutableList<Match> actual = scanner.findMatches("script.sh", -1, file);
    sw.stop();
    assertThat(actual.stream().map(m -> m.matchType).collect(Collectors.toList()))
        .containsExactly(MatchType.LICENSE);
    assertThat(actual.stream().map(m -> m.partyType).collect(Collectors.toList()))
        .containsExactly(PartyType.THIRD_PARTY);
    // Fail if protections against excessive backtracking seem to fail.
    assertThat(sw.elapsed().getSeconds()).isLessThan(8L); // normally 1s
  }

  @Test
  public void testFindMatch_fullApache2License() throws Exception {
    MatchType[] otherThanLicense = {MatchType.AUTHOR_OWNER};
    PartyType[] otherThan1p = {PartyType.THIRD_PARTY, PartyType.FORBIDDEN, PartyType.UNKNOWN};
    CopyrightScanner scanner = newScanner();
    ImmutableList<Match> actual = scanner.findMatches("LICENSE", -1, fullApache2Text());
    assertThat(actual.stream().map(m -> m.matchType).collect(Collectors.toList()))
        .containsNoneIn(otherThanLicense);
    assertThat(actual.stream().map(m -> m.partyType).collect(Collectors.toList()))
        .containsNoneIn(otherThan1p);
  }

  private CopyrightScanner newScanner() {
    RuleSet rules = builder.build();
    return new CopyrightScanner(
        rules.firstPartyLicenses,
        rules.thirdPartyLicenses,
        rules.forbiddenLicenses,
        rules.firstPartyOwners,
        rules.thirdPartyOwners,
        rules.forbiddenOwners,
        rules.excludePatterns);
  }

  private IndexedLineReader fullApache2Text() {
    return new IndexedLineReader(
        "LICENSE",
        -1,
        newInputStream(
            "\n"
                + "                                 Apache License\n"
                + "                           Version 2.0, January 2004\n"
                + "                        http://www.apache.org/licenses/\n"
                + "\n"
                + "   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n"
                + "\n"
                + "   1. Definitions.\n"
                + "\n"
                + "      \"License\" shall mean the terms and conditions for use, reproduction,\n"
                + "      and distribution as defined by Sections 1 through 9 of this document.\n"
                + "\n"
                + "      \"Licensor\" shall mean the copyright owner or entity authorized by\n"
                + "      the copyright owner that is granting the License.\n"
                + "\n"
                + "      \"Legal Entity\" shall mean the union of the acting entity and all\n"
                + "      other entities that control, are controlled by, or are under common\n"
                + "      control with that entity. For the purposes of this definition,\n"
                + "      \"control\" means (i) the power, direct or indirect, to cause the\n"
                + "      direction or management of such entity, whether by contract or\n"
                + "      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n"
                + "      outstanding shares, or (iii) beneficial ownership of such entity.\n"
                + "\n"
                + "      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n"
                + "      exercising permissions granted by this License.\n"
                + "\n"
                + "      \"Source\" form shall mean the preferred form for making modifications,\n"
                + "      including but not limited to software source code, documentation\n"
                + "      source, and configuration files.\n"
                + "\n"
                + "      \"Object\" form shall mean any form resulting from mechanical\n"
                + "      transformation or translation of a Source form, including but\n"
                + "      not limited to compiled object code, generated documentation,\n"
                + "      and conversions to other media types.\n"
                + "\n"
                + "      \"Work\" shall mean the work of authorship, whether in Source or\n"
                + "      Object form, made available under the License, as indicated by a\n"
                + "      copyright notice that is included in or attached to the work\n"
                + "      (an example is provided in the Appendix below).\n"
                + "\n"
                + "      \"Derivative Works\" shall mean any work, whether in Source or Object\n"
                + "      form, that is based on (or derived from) the Work and for which the\n"
                + "      editorial revisions, annotations, elaborations, or other modifications\n"
                + "      represent, as a whole, an original work of authorship. For the purposes\n"
                + "      of this License, Derivative Works shall not include works that remain\n"
                + "      separable from, or merely link (or bind by name) to the interfaces of,\n"
                + "      the Work and Derivative Works thereof.\n"
                + "\n"
                + "      \"Contribution\" shall mean any work of authorship, including\n"
                + "      the original version of the Work and any modifications or additions\n"
                + "      to that Work or Derivative Works thereof, that is intentionally\n"
                + "      submitted to Licensor for inclusion in the Work by the copyright owner\n"
                + "      or by an individual or Legal Entity authorized to submit on behalf of\n"
                + "      the copyright owner. For the purposes of this definition, \"submitted\"\n"
                + "      means any form of electronic, verbal, or written communication sent\n"
                + "      to the Licensor or its representatives, including but not limited to\n"
                + "      communication on electronic mailing lists, source code control systems,\n"
                + "      and issue tracking systems that are managed by, or on behalf of, the\n"
                + "      Licensor for the purpose of discussing and improving the Work, but\n"
                + "      excluding communication that is conspicuously marked or otherwise\n"
                + "      designated in writing by the copyright owner as \"Not a Contribution.\"\n"
                + "\n"
                + "      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n"
                + "      on behalf of whom a Contribution has been received by Licensor and\n"
                + "      subsequently incorporated within the Work.\n"
                + "\n"
                + "   2. Grant of Copyright License. Subject to the terms and conditions of\n"
                + "      this License, each Contributor hereby grants to You a perpetual,\n"
                + "      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n"
                + "      copyright license to reproduce, prepare Derivative Works of,\n"
                + "      publicly display, publicly perform, sublicense, and distribute the\n"
                + "      Work and such Derivative Works in Source or Object form.\n"
                + "\n"
                + "   3. Grant of Patent License. Subject to the terms and conditions of\n"
                + "      this License, each Contributor hereby grants to You a perpetual,\n"
                + "      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n"
                + "      (except as stated in this section) patent license to make, have made,\n"
                + "      use, offer to sell, sell, import, and otherwise transfer the Work,\n"
                + "      where such license applies only to those patent claims licensable\n"
                + "      by such Contributor that are necessarily infringed by their\n"
                + "      Contribution(s) alone or by combination of their Contribution(s)\n"
                + "      with the Work to which such Contribution(s) was submitted. If You\n"
                + "      institute patent litigation against any entity (including a\n"
                + "      cross-claim or counterclaim in a lawsuit) alleging that the Work\n"
                + "      or a Contribution incorporated within the Work constitutes direct\n"
                + "      or contributory patent infringement, then any patent licenses\n"
                + "      granted to You under this License for that Work shall terminate\n"
                + "      as of the date such litigation is filed.\n"
                + "\n"
                + "   4. Redistribution. You may reproduce and distribute copies of the\n"
                + "      Work or Derivative Works thereof in any medium, with or without\n"
                + "      modifications, and in Source or Object form, provided that You\n"
                + "      meet the following conditions:\n"
                + "\n"
                + "      (a) You must give any other recipients of the Work or\n"
                + "          Derivative Works a copy of this License; and\n"
                + "\n"
                + "      (b) You must cause any modified files to carry prominent notices\n"
                + "          stating that You changed the files; and\n"
                + "\n"
                + "      (c) You must retain, in the Source form of any Derivative Works\n"
                + "          that You distribute, all copyright, patent, trademark, and\n"
                + "          attribution notices from the Source form of the Work,\n"
                + "          excluding those notices that do not pertain to any part of\n"
                + "          the Derivative Works; and\n"
                + "\n"
                + "      (d) If the Work includes a \"NOTICE\" text file as part of its\n"
                + "          distribution, then any Derivative Works that You distribute must\n"
                + "          include a readable copy of the attribution notices contained\n"
                + "          within such NOTICE file, excluding those notices that do not\n"
                + "          pertain to any part of the Derivative Works, in at least one\n"
                + "          of the following places: within a NOTICE text file distributed\n"
                + "          as part of the Derivative Works; within the Source form or\n"
                + "          documentation, if provided along with the Derivative Works; or,\n"
                + "          within a display generated by the Derivative Works, if and\n"
                + "          wherever such third-party notices normally appear. The contents\n"
                + "          of the NOTICE file are for informational purposes only and\n"
                + "          do not modify the License. You may add Your own attribution\n"
                + "          notices within Derivative Works that You distribute, alongside\n"
                + "          or as an addendum to the NOTICE text from the Work, provided\n"
                + "          that such additional attribution notices cannot be construed\n"
                + "          as modifying the License.\n"
                + "\n"
                + "      You may add Your own copyright statement to Your modifications and\n"
                + "      may provide additional or different license terms and conditions\n"
                + "      for use, reproduction, or distribution of Your modifications, or\n"
                + "      for any such Derivative Works as a whole, provided Your use,\n"
                + "      reproduction, and distribution of the Work otherwise complies with\n"
                + "      the conditions stated in this License.\n"
                + "\n"
                + "   5. Submission of Contributions. Unless You explicitly state otherwise,\n"
                + "      any Contribution intentionally submitted for inclusion in the Work\n"
                + "      by You to the Licensor shall be under the terms and conditions of\n"
                + "      this License, without any additional terms or conditions.\n"
                + "      Notwithstanding the above, nothing herein shall supersede or modify\n"
                + "      the terms of any separate license agreement you may have executed\n"
                + "      with Licensor regarding such Contributions.\n"
                + "\n"
                + "   6. Trademarks. This License does not grant permission to use the trade\n"
                + "      names, trademarks, service marks, or product names of the Licensor,\n"
                + "      except as required for reasonable and customary use in describing the\n"
                + "      origin of the Work and reproducing the content of the NOTICE file.\n"
                + "\n"
                + "   7. Disclaimer of Warranty. Unless required by applicable law or\n"
                + "      agreed to in writing, Licensor provides the Work (and each\n"
                + "      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n"
                + "      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n"
                + "      implied, including, without limitation, any warranties or conditions\n"
                + "      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n"
                + "      PARTICULAR PURPOSE. You are solely responsible for determining the\n"
                + "      appropriateness of using or redistributing the Work and assume any\n"
                + "      risks associated with Your exercise of permissions under this License.\n"
                + "\n"
                + "   8. Limitation of Liability. In no event and under no legal theory,\n"
                + "      whether in tort (including negligence), contract, or otherwise,\n"
                + "      unless required by applicable law (such as deliberate and grossly\n"
                + "      negligent acts) or agreed to in writing, shall any Contributor be\n"
                + "      liable to You for damages, including any direct, indirect, special,\n"
                + "      incidental, or consequential damages of any character arising as a\n"
                + "      result of this License or out of the use or inability to use the\n"
                + "      Work (including but not limited to damages for loss of goodwill,\n"
                + "      work stoppage, computer failure or malfunction, or any and all\n"
                + "      other commercial damages or losses), even if such Contributor\n"
                + "      has been advised of the possibility of such damages.\n"
                + "\n"
                + "   9. Accepting Warranty or Additional Liability. While redistributing\n"
                + "      the Work or Derivative Works thereof, You may choose to offer,\n"
                + "      and charge a fee for, acceptance of support, warranty, indemnity,\n"
                + "      or other liability obligations and/or rights consistent with this\n"
                + "      License. However, in accepting such obligations, You may act only\n"
                + "      on Your own behalf and on Your sole responsibility, not on behalf\n"
                + "      of any other Contributor, and only if You agree to indemnify,\n"
                + "      defend, and hold each Contributor harmless for any liability\n"
                + "      incurred by, or claims asserted against, such Contributor by reason\n"
                + "      of your accepting any such warranty or additional liability.\n"
                + "\n"
                + "   END OF TERMS AND CONDITIONS\n"
                + "\n"
                + "   APPENDIX: How to apply the Apache License to your work.\n"
                + "\n"
                + "      To apply the Apache License to your work, attach the following\n"
                + "      boilerplate notice, with the fields enclosed by brackets \"[]\"\n"
                + "      replaced with your own identifying information. (Don't include\n"
                + "      the brackets!)  The text should be enclosed in the appropriate\n"
                + "      comment syntax for the file format. We also recommend that a\n"
                + "      file or class name and description of purpose be included on the\n"
                + "      same \"printed page\" as the copyright notice for easier\n"
                + "      identification within third-party archives.\n"
                + "\n"
                + "   Copyright [yyyy] [name of copyright owner]\n"
                + "\n"
                + "   Licensed under the Apache License, Version 2.0 (the \"License\");\n"
                + "   you may not use this file except in compliance with the License.\n"
                + "   You may obtain a copy of the License at\n"
                + "\n"
                + "       http://www.apache.org/licenses/LICENSE-2.0\n"
                + "\n"
                + "   Unless required by applicable law or agreed to in writing, software\n"
                + "   distributed under the License is distributed on an \"AS IS\" BASIS,\n"
                + "   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
                + "   See the License for the specific language governing permissions and\n"
                + "   limitations under the License."));
  }

  private IndexedLineReader largeFile(String embeddedText) {
    StringBuilder sb = new StringBuilder();
    sb.append("                                                                ");
    sb.append(sb); // 128
    sb.append(sb); // 256
    sb.append(sb); // 512
    sb.append(sb); // 1024
    sb.append('\n');
    String onek = sb.toString();
    sb.setLength(0);
    for (int i = 0; i < 256; i++) {
      sb.append(String.format(" x%2x", i));
    }
    sb.append('\n');
    String mixed1k = sb.toString();
    for (int j = 0; j < 4; j++) {
      for (int i = 0; i < 16; i++) {
        sb.append(onek);
      }
      for (int i = 0; i < 48; i++) {
        sb.append(onek, 0, 512 - 10 * i);
        sb.append(mixed1k, 512 + 10 * i, mixed1k.length());
      }
      if (j == 1) {
        sb.append(embeddedText);
        sb.append('\n');
      }
    }

    return new IndexedLineReader("big_file", -1, newInputStream(sb.toString()));
  }

  private IndexedLineReader readerFromString(String text) {
    return new IndexedLineReader("test", -1, newInputStream(text));
  }

  private InputStream newInputStream(String text) {
    return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
  }
}
