#!/usr/bin/env -S awk -E
#
# wrapper for the prtverify modules, 
# inspired by Johannes and Juergen's bash script

@include "/usr/lib/prtverify/00_prtverify_lib.awk"

function usage() {
    message = "Usage: prtverify [options] dir1 [dir2 ...]\n" 
    message = (message "options:\n  -l <loglevel>\n  -m clean-repo\n")
    message = (message "  -m [missing-deps|file-conflict] -c repo1 [-c repo2 ...]\n")
    print message > "/dev/stderr"
    exit 1
}

function readcollections() {
    if (typeof(COLLECTIONS) != "array") {
        usr_error("Need one or more collections. Use -c option to set.")
        exit 1
    }
    for (c in COLLECTIONS) {
        CollSize = 0
        while ((("ls -1 --color=none " c "/*/Pkgfile 2>/dev/null") | getline cP) > 0) {
            CollSize++
            if (mode["MD"] == 1) {
                sub(/\/Pkgfile$/,"",cP)
                DEPENDABLE[gensub(/.*\//,"","g",cP)]
            }
        }
        if (CollSize == 0) {
            usr_error(c " is not a valid CRUX port collection.")
            exit 1
        }
    }
    if (mode["FC"] == 1) {
	FS_sav=FS
        FS="\t"
        for (c in COLLECTIONS) {
            while ((("ls -1 --color=none " c "/*/.footprint 2>/dev/null") | getline cF) > 0) {
                COLLPORT = collectionport(fullpath( gensub(/\/\.footprint/, "", 1, cF) ))
                while ( (getline < cF) > 0 ) {
		    if ($3 ~ /\/$/) { continue; }
                    sub(/ -> .*/, "", $3)
                    if (! ($3 in fc_map)) { fc_map[$3] = COLLPORT }
                    else { fc_map[$3] = ( fc_map[$3] ":" COLLPORT ) }
                }
                close(cF)
            }
        }
	FS=FS_sav
    }
}

function readwhitelist() {
    WL_CMD="ls -1 --color=none /usr/lib/prtverify/*.wl 2>/dev/null"
    while ( (WL_CMD | getline wl) > 0 ) {
        if (system("test -f " wl) != 0) {
            usr_error("Error: " wl " not a regular file!")   
            continue
        }
        while ((getline line < wl) > 0) {
            WLIST[line]
        }
    close(wl)
    }
}

function parse_opt(i) {
    if (! (i+1 in ARGV)) { usage() }
    if ((ARGV[i] " " ARGV[i+1]) == "-m clean-repo") { mode["CR"]=1 }
    else if ((ARGV[i] " " ARGV[i+1]) == "-m missing-deps") { mode["MD"]=1 }
    else if ((ARGV[i] " " ARGV[i+1]) == "-m file-conflict") { mode["FC"]=1 }
    else if (ARGV[i] == "-m") { usage() }
    else if (ARGV[i] == "-c") { COLLECTIONS[ARGV[i+1]] }
    else if (ARGV[i] == "-l") { 
      if (ARGV[i+1] <1 || ARGV[i+1] >15) {
        usr_error("Invalid loglevel, using 15")
      } else {
        LOG_LEVEL=ARGV[i+1]
      }
    }
    else { usage() }
    delete ARGV[i]
    delete ARGV[i+1]
}

BEGIN {
    for (i=1; i<ARGC; i++) {
        if (ARGV[i] ~ /^-.$/) { parse_opt(i); i++ } else { TARGETS[ARGV[i]] }
    }
    delete ARGV
    ARGC=1
    for (t in TARGETS) {
        if (system("test -d " t) != 0) {
            usr_error(t " is not a directory, ignoring")
        } else {
            for (f in PF) {
                p = fullpath(t) "/" f
                if (system("test -f " p) == 0) { ARGV[ARGC] = p; ARGC++ }
                else if(loglevel_ok(FATAL)) { perror(FATAL, "file not found: " p) }
            }
        }
    }

    if (ARGC == 1) { usage() }
    readwhitelist()
    if (mode["FC"] + mode["MD"] > 0) { readcollections() }
}

FNR==1 {
  # conduct the tests that don't require reading the file
  # (the clean-repo test, for example)
  if ((mode["CR"] == 1) && loglevel_ok(FATAL) && FILENAME ~ PKGFILE) {
      dir = gensub(/\/Pkgfile/,"","g",FILENAME)
      while ( ("ls -1 --color=none " dir) | getline f ) {
          if (f ~ /(\.(rar|svn|tgz|tzst|tar.(bz2|gz|lz|xz|zst)|zip)|CVS|REPO|index.html)$/)
                perror(FATAL, "invalid file/directory: " f)
      }
  }
  # some modules will require COLLPORT to be defined; let's do that here
  if (FILENAME ~ PKGFILE) {
      COLLPORT = collectionport(fullpath(gensub(/\/Pkgfile/, "", 1, FILENAME)))
  }
}

# load additional modules below
@include "/usr/lib/prtverify/20_encoding.awk"
@include "/usr/lib/prtverify/20_evil_cmds.awk"
@include "/usr/lib/prtverify/20_maintainer_email.awk"
@include "/usr/lib/prtverify/20_missing_deps.awk"
@include "/usr/lib/prtverify/20_pkgfile_functions.awk"
@include "/usr/lib/prtverify/20_pkgfile_headers.awk"
@include "/usr/lib/prtverify/20_pkgfile_vars.awk"
@include "/usr/lib/prtverify/20_redundant_deps.awk"
@include "/usr/lib/prtverify/30_file_conflict.awk"
@include "/usr/lib/prtverify/30_file_permissions.awk"
@include "/usr/lib/prtverify/30_filesystem_collisions.awk"
@include "/usr/lib/prtverify/30_invalid_dirs.awk"
@include "/usr/lib/prtverify/30_junk_files.awk"
@include "/usr/lib/prtverify/30_suid_sgid.awk"
@include "/usr/lib/prtverify/30_system_users.awk"
