/*
 * Copyright 2013-2019, Centre for Genomic Regulation (CRG)
 *
 * 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.
 */

import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * Implement capsule custom strategy to add maven dependencies as
 * a command line argument
 *
 * @author Paolo Di Tommaso <paolo.ditommaso@gmail.com>
 */
public class CapsuleLoader extends Capsule {

    private static Pattern IGNORE_REGEX = Pattern.compile("Could not find artifact io.seqera:nf-tower-client.* in central");

    private static Field stderr;

    static {
        try {
            stderr = Capsule.class.getDeclaredField("STDERR");
            stderr.setAccessible(true);

            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(stderr, stderr.getModifiers() & ~Modifier.FINAL);

            stderr.set(null, new FilterPrintStream(System.err));
        }
        catch (Exception e) {
            System.err.println("WARN: Failed to install capsule custom stderr filter -- " + e.getMessage());
        }
    }

    static class FilterPrintStream extends PrintStream {
        FilterPrintStream(PrintStream target) {
            super(target);
        }

        @Override
        public void println(String str) {
            if( !IGNORE_REGEX.matcher(str).find() ) {
                super.println(str);
            }
        }
    }


    /**
     * Constructs a capsule from the given JAR file
     *
     * @param jarFile  the path to the JAR file
     */
    protected CapsuleLoader(Path jarFile) {
        super(jarFile);
    }

    @Override
    protected ProcessBuilder prelaunch(List<String> jvmArgs, List<String> args) {
        ProcessBuilder pb = super.prelaunch(jvmArgs, args);

        String drip = System.getenv().get("NXF_DRIP");
        if( drip != null && !drip.isEmpty() ) {
            pb.command().set(0, drip);
            return pb;
        }

        return pb;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected <T> T attribute(Map.Entry<String, T> attr) {

        if (ATTR_DEPENDENCIES == attr && System.getenv("NXF_GRAB") != null ) {
            String deps = System.getenv("NXF_GRAB");
            List<String> parent = super.attribute((Map.Entry<String,List<String>>)attr);
            return (T)extendDepsWith(deps, parent);
        }

        if (ATTR_APP_CLASS_PATH == attr && System.getenv("NXF_CLASSPATH") != null) {
            String classpath = System.getenv("NXF_CLASSPATH");
            List<String> parent = super.attribute((Map.Entry<String, List<String>>)attr);
            return (T)extendClassPathWith(classpath, parent);
        }

        return super.attribute(attr);
    }

    static List<String> extendClassPathWith(String classpath, List<String> origin) {
        if( classpath == null || "".equals(classpath.trim()) ) {
            return origin;
        }

        List<String> result = new ArrayList<>();
        if( origin != null ) {
            result.addAll(origin);
        }

        for( String lib : classpath.split(":") ) {
            String trimmed = lib.trim();
            if( trimmed.length()>0 )
                result.add(trimmed);
        }

        return result;
    }

    /*
     * get a blank separated list of dependencies
     * having the "maven" syntax i.e. group:name:version
     */
    static List<String> extendDepsWith(String dependencies, List<String> origin) {
        if( dependencies == null || "".equals(dependencies.trim()) ) {
            return origin;
        }

        // split by black
        List<String> result = new ArrayList<>();
        for( String dep : dependencies.split(" |\n") ) {
            String trimmed = dep.trim();
            if( trimmed.length()>0 )
                result.add(trimmed);
        }

        // add all the inherited if any
        if( origin != null && origin.size()>0 ) {
            result.addAll(0, origin);
        }

        return result;
    }

}

@@ -623,103 +623,8 @@
 */%0A%0A
-import java.io.PrintStream;%0Aimport java.lang.reflect.Field;%0Aimport java.lang.reflect.Modifier;%0A
 impo
@@ -646,16 +646,16 @@
 e.Path;%0A
+
 import j
@@ -722,40 +722,8 @@
 Map;
-%0Aimport java.util.regex.Pattern;
 %0A%0A/*
@@ -880,16 +880,16 @@
 om%3E%0A */%0A
+
 public c
@@ -930,1066 +930,8 @@
  %7B%0A%0A
-    private static Pattern IGNORE_REGEX = Pattern.compile(%22Could not find artifact io.seqera:nf-tower-client.* in central%22);%0A%0A    private static Field stderr;%0A%0A    static %7B%0A        try %7B%0A            stderr = Capsule.class.getDeclaredField(%22STDERR%22);%0A            stderr.setAccessible(true);%0A%0A            Field modifiersField = Field.class.getDeclaredField(%22modifiers%22);%0A            modifiersField.setAccessible(true);%0A            modifiersField.setInt(stderr, stderr.getModifiers() & ~Modifier.FINAL);%0A%0A            stderr.set(null, new FilterPrintStream(System.err));%0A        %7D%0A        catch (Exception e) %7B%0A            System.err.println(%22WARN: Failed to install capsule custom stderr filter -- %22 + e.getMessage());%0A        %7D%0A    %7D%0A%0A    static class FilterPrintStream extends PrintStream %7B%0A        FilterPrintStream(PrintStream target) %7B%0A            super(target);%0A        %7D%0A%0A        @Override%0A        public void println(String str) %7B%0A            if( !IGNORE_REGEX.matcher(str).find() ) %7B%0A                super.println(str);%0A            %7D%0A        %7D%0A    %7D%0A%0A%0A
     

Revert "Patch capsule error message"