
/*
 * 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.
 */

import java.io.*;
import org.codehaus.plexus.util.*;

boolean result = true;

try
{
    // Generated files checks
    File apidocs1 = new File( basedir, "module1/target/site/apidocs" );
    if ( !apidocs1.exists() || !apidocs1.isDirectory() )
    {
        System.err.println( apidocs1.getAbsolutePath() + " dir is missing or a directory." );
        return false;
    }
    File apidocs2 = new File( basedir, "module2/target/site/apidocs" );
    if ( !apidocs2.exists() || !apidocs2.isDirectory() )
    {
        System.err.println( apidocs2.getAbsolutePath() + " dir is missing or a directory." );
        return false;
    }

    File options1 = new File( apidocs1, "options" );
    if ( !options1.exists() || !options1.isFile() )
    {
        System.err.println( options1.getAbsolutePath() + " file is missing or not a file." );
        return false;
    }
    File options2 = new File( apidocs2, "options" );
    if ( !options2.exists() || !options2.isFile() )
    {
        System.err.println( options2.getAbsolutePath() + " file is missing or not a file." );
        return false;
    }

    // Read files
    String contentOptions1 = FileUtils.fileRead( options1 );
    String contentOptions2 = FileUtils.fileRead( options2 );
    String log = FileUtils.fileRead( new File( basedir, "build.log" ) );

    // Generated files content checks
    if ( contentOptions1.contains( "module2" ) )
    { // module1 does not depend on module2, then it should not link
        System.err.println( "module1 -linkoffline module2 added: " + options1 );
        return false;
    }
    int link1 = contentOptions1.indexOf( "-link" );
    if ( link1 == -1 )
    {
        System.err.println( "-link not added: " + options1 );
        return false;
    }
    if ( !contentOptions1.substring( link1 ).contains( "http://commons.apache.org/lang/apidocs" ) )
    {
        System.err.println( "link for commons-lang not added: " + options1 );
        if ( !log.contains( "Error fetching link: http://commons.apache.org/lang/apidocs" ) )
        {
            return false;
        }
    }
    if ( !contentOptions1.substring( link1 ).contains( "http://junit.org/apidocs" ) )
    {
        System.err.println( "link for junit not added: " + options1 );
        if ( !log.contains( "Error fetching link: http://junit.org/apidocs" ) )
        {
            return false;
        }
    }
    if ( contentOptions1.contains( "http://maven.apache.org/maven2/maven-script/maven-script-marmalade/apidocs" ) )
    {
        System.err.println( "link for maven-script-marmalade added: " + options1 );
        return false;
    }

    int linkoffline2 = contentOptions2.indexOf( "module1" );
    if ( linkoffline2 < 0 )
    { // module2 depends on module1, then it should link
        System.err.println( "module2 -linkoffline module1 not added: " + options2 );
        return false;
    }
    if ( !contentOptions2.substring( linkoffline2 ).contains( apidocs1.getAbsolutePath().replaceAll( "\\\\", "/" ) ) )
    {
        System.err.println( apidocs1.getAbsolutePath().replaceAll( "\\\\", "/" ) + " not added: " + options2 );
        return false;
    }
    int link2 = contentOptions2.indexOf( "-link" );
    if ( link2 == -1 )
    {
        System.err.println( "-link not added: " + options2 );
        return false;
    }
    if ( !contentOptions2.substring( link2 ).contains( "http://commons.apache.org/lang/apidocs" ) )
    {
        System.err.println( "link for commons-lang not added: " + options2 );
        if ( !log.contains( "Error fetching link: http://commons.apache.org/lang/apidocs" ) )
        {
            return false;
        }
    }
    if ( !contentOptions2.substring( link2 ).contains( "http://junit.org/apidocs" ) )
    {
        System.err.println( "link for junit not added: " + options2 );
        if ( !log.contains( "Error fetching link: http://junit.org/apidocs" ) )
        {
            return false;
        }
    }
    if ( contentOptions2.contains( "http://maven.apache.org/maven2/maven-script/maven-script-marmalade/apidocs" ) )
    {
        System.err.println( "link for maven-script-marmalade added: " + options2 );
        return false;
    }
}
catch( RuntimeException e )
{
    e.printStackTrace();
    return false;
}

return result;
