#!/usr/bin/perl
################################################################################
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.
################################################################################
# This script verifies that the dependencies shipped in the Kudu jars do not
# change over time without us noticing.
################################################################################
use strict;
use warnings;

# Prefix for shaded classes.
my $pat_kudu_shaded_prefix = qr{^org/apache/kudu/shaded/};

# Allowed filenames of non-Java files in JARs.
my $pat_allow_non_java =
    qr{(?:\.(?:txt|xml|properties|json|proto|MF|jnilib|pro|so|swp)|
          LICENSE|NOTICE|DEPENDENCIES|
          # The kudu-spark DataSourceRegister file.
          DataSourceRegister|
          # Netty's block hound integration file.
          reactor\.blockhound\.integration\.BlockHoundIntegration)$}x;

# Allowed filenames of shaded dependencies in JARs.
my $pat_allow_kudu_shaded =
    qr{^org/apache/kudu/shaded/
        (?:com/google/(?:common|gson|gradle/osdetector|protobuf|thirdparty/publicsuffix)|
           com/sangupta/murmur|
           kr/motd/maven|
           org/apache/(?:commons|http)|
           org/checkerframework|
           org/HdrHistogram|
           org/LatencyUtils|
           io/micrometer|
           io/netty|
           scopt)
      }x;

# Allowed paths of unshaded Kudu dependencies in JARs.
# Currently, there is no restriction imposed for org.apache.kudu classes.
my $pat_allow_kudu_unshaded = qr{^org/apache/kudu/.*};

# Allowed paths of unshaded non-Kudu dependencies in JARs.
my $pat_allow_nonkudu_unshaded = qr{^(?:com/databricks/spark/avro|
                                        com/stumbleupon/async/|
                                        org/apache/parquet/|
                                        org/apache/yetus/)}x;

if (scalar @ARGV != 1) {
  print STDERR "Usage: $0 <dest_dir>\n";
  exit 1;
}

my $dest_dir = $ARGV[0];
chdir($dest_dir) or die "cannot chdir to destination directory $dest_dir: $!";
print "Checking jars in directory: " . `pwd`;

chomp(my @jars = `find . -type f -name \*.jar |
                         grep -v build/jars |
                         grep -v tests\.jar |
                         grep -v tests-shaded\.jar |
                         grep -v original |
                         grep -v sources\.jar |
                         grep -v javadoc\.jar |
                         grep -v unshaded\.jar |
                         grep -v buildSrc.jar |
                         grep -v gradle-wrapper.jar |
                         # Ignored because it's test only and unpublished.
                         grep -v kudu-jepsen.*\.jar |
                         # Ignored because it's a tool jar that shades everything.
                         grep -v kudu-backup-tools.*\.jar |
                         # Ignored because it's an internal jar that shades everything.
                         grep -v kudu-subprocess.*\.jar`
                         );

my $num_errors = 0;

foreach my $jar (@jars) {
  print "> $jar\n";
  chomp(my @files = `jar tf $jar`);
  foreach my $file (@files) {
    # In each case, ensure the files match the expected patterns.
    if ($file =~ qr{/$}) {
      # A directory. Skip.
    } elsif ($file !~ qr{\.class$}) {
      # Non-Java stuff.
      if ($file !~ $pat_allow_non_java) {
        $num_errors++;
        print "NON_JAVA $file\n";
      }
    } elsif ($file =~ $pat_kudu_shaded_prefix) {
      # Shaded Kudu classes.
      if ($file !~ $pat_allow_kudu_shaded) {
        $num_errors++;
        print "KUDU_SHADED $file\n";
      }
    } elsif ($file =~ qr{^org/apache/kudu}) {
      # Unshaded Kudu classes.
      if ($file !~ $pat_allow_kudu_unshaded) {
        $num_errors++;
        print "KUDU_UNSHADED $file\n";
      }
    } else {
      # Non-Kudu classes.
      if ($file !~ $pat_allow_nonkudu_unshaded) {
        $num_errors++;
        print "NON_KUDU $file\n";
      }
    }
  }
}

if ($num_errors != 0) {
  print "Found $num_errors errors.\n";
  exit 1;
}
print "OK.\n";
exit 0;
