/*
 * Copyright 2014-2018 Real Logic Ltd.
 *
 * 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.
 */
package io.aeron.cluster;

import io.aeron.archive.client.AeronArchive;
import io.aeron.cluster.codecs.cnc.ClusterComponentType;
import io.aeron.cluster.codecs.cnc.CncHeaderDecoder;
import io.aeron.cluster.service.RecordingLog;

import java.io.File;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

public class ClusterTool
{
    private static final long TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5);

    private static File clusterDir;

    public static void main(final String[] args)
    {
        if (args.length == 0 || args.length > 3)
        {
            printHelp();
            System.exit(-1);
        }

        clusterDir = new File(args[0]);
        if (!clusterDir.exists())
        {
            System.err.println("ERR: cluster folder not found: " + clusterDir.getAbsolutePath());
            printHelp();
            System.exit(-1);
        }

        if (args.length == 2 && args[1].equals("describe"))
        {
            try (ClusterCncFile cncFile = openCncFile(System.out::println))
            {
                final CncHeaderDecoder decoder = cncFile.decoder();

                printTypeAndActivityTimestamp(decoder.fileType(), decoder.activityTimestamp());
                System.out.println(decoder);
            }
        }
        else if (args.length == 2 && args[1].equals("pid"))
        {
            try (ClusterCncFile cncFile = openCncFile(null))
            {
                System.out.println(cncFile.decoder().pid());
            }
        }
        else if (args.length == 2 && args[1].equals("recovery"))
        {
            final RecordingLog recordingLog = new RecordingLog(clusterDir);
            try (AeronArchive archive = AeronArchive.connect())
            {
                System.out.println(recordingLog.createRecoveryPlan(archive).toString());
            }
        }
    }

    private static ClusterCncFile openCncFile(final Consumer<String> logger)
    {
        return new ClusterCncFile(clusterDir, ClusterCncFile.FILENAME, System::currentTimeMillis, TIMEOUT_MS, logger);
    }

    private static void printTypeAndActivityTimestamp(final ClusterComponentType type, final long activityTimestamp)
    {
        System.out.print("Type: " + type);
        System.out.format(
            " %1$tH:%1$tM:%1$tS (activity: %2$tH:%2$tM:%2$tS)%n", new Date(), new Date(activityTimestamp));
    }

    private static void printHelp()
    {
        System.out.println("Usage: <cluster-dir> <command> <optional args>");
        System.out.println("  describe: prints out all descriptors in the file. Optionally specify a recording id" +
            " to describe a single recording.");
        System.out.println("  pid: prints PID of cluster component.");
        System.out.println("  recovery: prints recovery plan of cluster component.");
    }
}

@@ -1046,45 +1046,8 @@
 );%0A%0A
-    private static File clusterDir;%0A%0A
     
@@ -1147,9 +1147,9 @@
 h %3E 
-3
+2
 )%0A  
@@ -1229,16 +1229,27 @@
         
+final File 
 clusterD
@@ -1507,35 +1507,92 @@
 gth == 2
- && args%5B1%5D.equals(
+)%0A        %7B%0A            switch (args%5B1%5D)%0A            %7B%0A                case 
 %22describ
@@ -1593,18 +1593,17 @@
 escribe%22
-))
+:
 %0A       
@@ -1595,34 +1595,32 @@
 cribe%22:%0A        
-%7B%0A
             try 
@@ -1657,16 +1657,28 @@
 CncFile(
+clusterDir, 
 System.o
@@ -1695,34 +1695,45 @@
 n))%0A            
-%7B%0A
+        %7B%0A   
                 
@@ -1728,24 +1728,29 @@
             
+     
 final CncHea
@@ -1789,17 +1789,24 @@
 oder();%0A
-%0A
+        
         
@@ -1901,32 +1901,40 @@
                 
+   
+     
 System.out.print
@@ -1950,32 +1950,40 @@
 r);%0A            
+        
 %7D%0A        %7D%0A    
@@ -1972,34 +1972,34 @@
   %7D%0A        
-%7D%0A
+  
         
 else if (arg
@@ -1990,59 +1990,45 @@
     
-else if (args.length == 2 && args%5B1%5D.equals(
+  break;%0A%0A                case 
 %22pid%22
-))
+:
 %0A   
@@ -2024,34 +2024,32 @@
  %22pid%22:%0A        
-%7B%0A
             try 
@@ -2086,16 +2086,28 @@
 CncFile(
+clusterDir, 
 null))%0A 
@@ -2109,34 +2109,50 @@
 l))%0A            
+      
-%7B%0A
+  %7B%0A        
                 
@@ -2200,34 +2200,32 @@
 ));%0A            
-%7D%0A
         %7D%0A      
@@ -2230,75 +2230,167 @@
     
-else if (args.length == 2 && args%5B1%5D.equals(%22recovery%22))%0A        %7B%0A
+            break;%0A%0A                case %22recovery%22:%0A                    try (AeronArchive archive = AeronArchive.connect())%0A                    %7B%0A            
     
@@ -2473,78 +2473,8 @@
     
-    try (AeronArchive archive = AeronArchive.connect())%0A            %7B%0A
     
@@ -2548,20 +2548,58 @@
 ive)
-.toString())
+);%0A                    %7D%0A                    break
 ;%0A  
@@ -2679,16 +2679,39 @@
 e(final 
+File clusterDir, final 
 Consumer
@@ -3271,24 +3271,8 @@
 and%3E
- %3Coptional args%3E
 %22);%0A

Tidy up ClusterTool.