/**
 * 
 */
package org.jboss.maven.plugins.dependency;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.IOUtil;

/**
 * @author lgao
 *
 */
@Mojo( name = "check", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true )
public class DependencyCheckMojo extends AbstractMojo
{
   private static final List<String> excludedGroupIds = new ArrayList<String>();
   static
   {
      excludedGroupIds.add("org.apache.maven.plugins");
   }
   
   // fields -----------------------------------------------------------------

   /**
    * The Maven project.
    */
   @Component
   private MavenProject project;
   
   /**
    * Which repository do you want to check against. Default is the maven central repository
    * The value is one of predefined remote repositories in the current active profiles.
    * 
    */
   @Parameter(property = "repoId", defaultValue = "central")
   private String repoId;
   
   
   /**
    * The output file which contains list of missing dependencies or plugins. Default is deps-list.txt in the target directory.
    * 
    */
   @Parameter(property = "output")
   private File output;
   
   public void execute() throws MojoExecutionException, MojoFailureException
   {
      
      String projectGroupId = project.getGroupId();
      
      // dependencies
      Set<Artifact> dependencies = project.getArtifacts();
      
      // plugins
      Set<Artifact> plugins = project.getPluginArtifacts();
      
      // collect all artifacts needed
      Set<Artifact> artifacts = new HashSet<Artifact>();
      artifacts.addAll(dependencies);
      artifacts.addAll(plugins);
      
      if (output == null)
      {
         output = new File(project.getBasedir() + "/target/deps-list.txt");
      }
      if (!output.getParentFile().exists())
      {
         output.getParentFile().mkdirs();
      }
      getLog().debug("Will record missing artifacts into: " + output.getAbsolutePath());

      ArtifactRepository repo = getArtifactRepository();
      if (repo == null)
      {
         throw new MojoFailureException("Unkown repository: " + this.repoId);
      }
      
      getLog().debug("Checking against repository: " + repo.getId());
      
      List<String> missingArtifacts = new ArrayList<String>();
      for (Artifact artifact: artifacts)
      {
         String groupId = artifact.getGroupId();
         if (projectGroupId.equals(groupId) || excludedGroupIds.contains(groupId))
         {
            getLog().debug("GroupId: " + groupId + " will be skipped.");
            continue;
         }
         String repoURL = repo.getUrl();
         if (!repoURL.endsWith("/"))
         {
            repoURL = repoURL + "/";
         }
         String artifactLink = repoURL + artifact.getGroupId().replaceAll("\\.", "/") + "/" + artifact.getArtifactId() + "/" + artifact.getVersion() + "/" + artifact.getArtifactId() + "-" + artifact.getVersion() + ".pom";
         getLog().debug("Checking artifact: " + gatv(artifact) + " at: " + artifactLink);
         HttpURLConnection urlConn = null;
         try
         {
            URL linkURL = new URL(artifactLink);
            urlConn = (HttpURLConnection)linkURL.openConnection();
            urlConn.connect();
            int code = urlConn.getResponseCode();
            if (code >= 400)
            {
               getLog().debug("\tNot found.");
               missingArtifacts.add(gatv(artifact));
            }
         }
         catch (IOException e)
         {
            getLog().warn("Wrong link: " + artifactLink, e);
         }
         finally
         {
            urlConn.disconnect();
         }
      }
      
      PrintWriter writer = null;
      try
      {
         writer = new PrintWriter(output);
         for (String artiStr: missingArtifacts)
         {
            getLog().debug(artiStr);
            writer.println(artiStr);
         }
      }
      catch (IOException e)
      {
         getLog().warn("Error to write data into file: " + output.getAbsolutePath(), e);
      }
      finally
      {
         IOUtil.close(writer);
      }
   }
   
   /**
    * Gets current ArtifactRepository which will be used to check against
    */
   private ArtifactRepository getArtifactRepository()
   {
      List<ArtifactRepository> artifactRepos = project.getRemoteArtifactRepositories();
      if (artifactRepos != null && artifactRepos.size() > 0)
      {
         for (ArtifactRepository artiRepo: artifactRepos)
         {
            if (artiRepo.getId().equals(this.repoId))
            {
               return artiRepo;
            }
         }
      }
      return null;
   }
   
   
   private String gatv(Artifact artifact)
   {
      StringBuilder sb = new StringBuilder();
      sb.append(artifact.getGroupId());
      sb.append(":");
      sb.append(artifact.getArtifactId());
      sb.append(":");
      sb.append(artifact.getType());
      sb.append(":");
      sb.append(artifact.getVersion());
      return sb.toString();
   }

}

@@ -1748,56 +1748,66 @@
 ns. 
-Default is deps-list.txt in the target directory
+%0A    * If not specified, it will print list to console out
 .%0A  
@@ -2421,83 +2421,196 @@
     
-output = new File(project.getBasedir() + %22/target/deps-list.txt%22
+getLog().debug(%22Will record missing artifacts into console out.%22);%0A      %7D%0A      else%0A      %7B%0A         getLog().info(%22Will record missing artifacts into: %22 + output.getAbsolutePath()
 );%0A   
-   %7D%0A
     
@@ -2647,32 +2647,35 @@
 exists())%0A      
+   
 %7B%0A         outpu
@@ -2669,16 +2669,19 @@
         
+ 
+  
 output.g
@@ -2715,98 +2715,20 @@
     
-%7D%0A
    
+%7D%0A
    
-getLog().debug(%22Will record missing artifacts into: %22 + output.getAbsolutePath());
+   %7D
 %0A%0A  
@@ -3271,28 +3271,36 @@
 ug(%22
-GroupId: %22 + groupId
+Artifact: %22 + gatv(artifact)
  + %22
@@ -3345,32 +3345,117 @@
 nue;%0A         %7D%0A
+         getLog().debug(%22Checking Artifact: %22 + gatv(artifact));%0A         %0A         %0A
          String 
@@ -4564,32 +4564,75 @@
     try%0A      %7B%0A
+         if (output != null)%0A         %7B%0A   
          writer 
@@ -4658,16 +4658,27 @@
 utput);%0A
+         %7D%0A
         
@@ -4781,32 +4781,179 @@
     
-writer.println(artiStr);
+if (writer != null)%0A            %7B%0A               writer.println(artiStr);%0A            %7D%0A            else%0A            %7B%0A               getLog().info(artiStr);%0A            %7D
 %0A   

Print to console output if there is no output file specified.