package com.sleekbyte.tailor.integration;

import com.sleekbyte.tailor.common.ExitCode;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.nio.charset.Charset;

/**
 * Integrates Tailor into supplied Xcode project.
 */
public final class XcodeIntegrator {

    /**
     * Integrate Tailor into supplied Xcode project as a build phase run script.
     *
     * @param xcodeprojPath relative/absolute path to a xcodeproj file
     */
    public static int setupXcode(String xcodeprojPath) {
        try {
            integrateTailor(getAbsolutePath(xcodeprojPath));
        } catch (IOException | InterruptedException e) {
            System.err.println("Could not add Tailor Build Phase Run Script to " + xcodeprojPath + "\nReason: "
                                + e.getMessage());
            return ExitCode.FAILURE;
        }

        return ExitCode.SUCCESS;
    }

    private static String getAbsolutePath(String path) throws IOException {
        File file = new File(path);
        if (file.isDirectory()
            && (path.endsWith(".xcodeproj/") || path.endsWith(".xcodeproj"))) {
            return file.getAbsolutePath();
        } else {
            throw new IOException(path + " is not a valid .xcodeproj");
        }
    }

    private static void integrateTailor(String absolutePath) throws IOException, InterruptedException {
        File tempScript = createTempRubyScript(absolutePath);

        try {
            ProcessBuilder pb = new ProcessBuilder("ruby", tempScript.toString());
            pb.inheritIO();
            Process process = pb.start();
            process.waitFor();
        } finally {
            if (!tempScript.delete()) {
                throw new FileNotFoundException("Failed to delete file " + tempScript );
            }
        }
    }

    private static File createTempRubyScript(String absolutePath) throws IOException {
        File tempScript = File.createTempFile("xcode_integrate", "rb");
        Writer streamWriter = new OutputStreamWriter(new FileOutputStream(tempScript), Charset.forName("UTF-8"));
        PrintWriter printWriter = new PrintWriter(streamWriter);

        printWriter.println("#!/usr/bin/env ruby");
        printWriter.println("ENV['GEM_HOME'] = '/usr/local/tailor/gems/installed'");
        printWriter.println("ENV['GEM_PATH'] = '/usr/local/tailor/gems/installed'");
        printWriter.println("cmd = \"gem install --local --no-rdoc --no-ri xcodeproj-0.27.0.gem\"");
        printWriter.println("Dir.chdir('/usr/local/tailor/gems/vendor/cache'){ %x[#{cmd}] }");
        printWriter.println("require 'xcodeproj'");
        printWriter.println("begin");
        printWriter.println(String.format("\tproject = Xcodeproj::Project.open(\"%s\")", absolutePath));
        printWriter.println("rescue");
        printWriter.println("\tabort(\"Integration Error: Invalid .xcodeproj file\")");
        printWriter.println("end");
        printWriter.println("main_target = project.targets.first");
        printWriter.println("phase = main_target.new_shell_script_build_phase(\"Tailor\")");
        printWriter.println("phase.shell_script = \"/usr/local/bin/tailor\"");
        printWriter.println("project.save()");

        printWriter.close();
        streamWriter.close();

        return tempScript;
    }
}

@@ -2314,19 +2314,79 @@
 er.print
-ln(
+(String.join(System.getProperty(%22line.separator%22),%0A            
 %22#!/usr/
@@ -2398,18 +2398,17 @@
 nv ruby%22
-);
+,
 %0A       
@@ -2408,36 +2408,20 @@
         
-printWriter.println(
+    
 %22ENV%5B'GE
@@ -2458,34 +2458,33 @@
 gems/installed'%22
-);
+,
 %0A        printWr
@@ -2476,36 +2476,20 @@
         
-printWriter.println(
+    
 %22ENV%5B'GE
@@ -2534,18 +2534,17 @@
 talled'%22
-);
+,
 %0A       
@@ -2544,36 +2544,20 @@
         
-printWriter.println(
+    
 %22cmd = %5C
@@ -2614,18 +2614,17 @@
 .27.
-0
+1
 .gem%5C%22%22
-);
+,
 %0A   
@@ -2628,36 +2628,20 @@
         
-printWriter.println(
+    
 %22Dir.chd
@@ -2696,18 +2696,17 @@
 cmd%7D%5D %7D%22
-);
+,
 %0A       
@@ -2706,36 +2706,20 @@
         
-printWriter.println(
+    
 %22require
@@ -2731,18 +2731,17 @@
 deproj'%22
-);
+,
 %0A       
@@ -2745,37 +2745,20 @@
     
-printWriter.println(
+    
 %22begin%22
-);
+,
 %0A   
@@ -2762,36 +2762,20 @@
         
-printWriter.println(
+    
 String.f
@@ -2836,26 +2836,25 @@
 bsolutePath)
-);
+,
 %0A        pri
@@ -2854,36 +2854,20 @@
     
-printWriter.println(
+    
 %22rescue%22
 );%0A 
@@ -2862,18 +2862,17 @@
 %22rescue%22
-);
+,
 %0A       
@@ -2872,36 +2872,20 @@
         
-printWriter.println(
+    
 %22%5Ctabort
@@ -2929,26 +2929,25 @@
 roj file%5C%22)%22
-);
+,
 %0A        pri
@@ -2947,35 +2947,18 @@
     
-printWriter.println(
+    
 %22end%22
-);
+,
 %0A   
@@ -2962,36 +2962,20 @@
         
-printWriter.println(
+    
 %22main_ta
@@ -3003,27 +3003,30 @@
 s.first%22
-);%0A
+,%0A    
         
 printWri
@@ -3017,36 +3017,16 @@
         
-printWriter.println(
 %22phase =
@@ -3079,18 +3079,17 @@
 ilor%5C%22)%22
-);
+,
 %0A       
@@ -3089,36 +3089,20 @@
         
-printWriter.println(
+    
 %22phase.s
@@ -3141,18 +3141,17 @@
 ailor%5C%22%22
-);
+,
 %0A       
@@ -3155,28 +3155,12 @@
     
-printWriter.println(
+    
 %22pro
@@ -3171,16 +3171,26 @@
 .save()%22
+%0A        )
 );%0A%0A    

Refactor ruby script creation