package com.urbancode.air.plugin.scm

import com.urbancode.air.*

import java.io.File
import java.util.Date
import java.util.regex.Pattern
import com.urbancode.commons.util.IO
import org.apache.commons.lang.math.RandomUtils

abstract public class SCMStep {

    //**************************************************************************
    // CLASS
    //**************************************************************************
    static protected final String REPO_TYPE = 'clearcase'

    //**************************************************************************
    // INSTANCE
    //**************************************************************************
    String scmCommand = "cleartool"

    File directory
    def viewName
    def viewPath
    boolean useTags
    def loadRules
    def hostStorPath
    def globStorPath
    def hostname
    boolean ptime
    def tmode
    def streamName
    def vobName
    String strategy

    CommandHelper ch 
    
    protected void setupWorkDir() {
        if (strategy == "useExisting") {
            directory = new File(viewPath);
        }
        else {
            directory = new File(viewName).getAbsoluteFile();
        }
        
        if (!directory.exists()) {
            if (directory.isFile()) {
                throw new IllegalArgumentException("Working directory ${directory} is a file!")
            }
            directory.mkdirs()
        }
        ch = new CommandHelper(directory)
    }

    protected boolean checkExistingView() {
        //use lsview to establish if the view exists
        def exitCode = 0
        ch.ignoreExitValue(true)
        boolean result = true
        def command = [scmCommand, 'lsview', '-storage', viewPath + File.separator + viewName]
        exitCode = ch.runCommand("Checking if the view exists", command) { Process proc ->
            proc.out.close()
            proc.consumeProcessErrorStream(System.out)
            println proc.text
        }
            
        if (exitCode != 0) {
            result = false
        }

        //we need to check if there is a tag for this viewName yet
        if (useTags && !result) {
            command = [scmCommand, 'lsview', viewName]
            exitCode = ch.runCommand("Checking if there is a tag for $viewName", command) { Process proc ->
                proc.out.close()
                proc.consumeProcessErrorStream(System.out)
                println proc.text
            }
            if (exitCode != 0) {
                result = false
            }
        }
        ch.ignoreExitValue(false)
        return result
    }

    protected void removeView() {
        File viewParentDir = directory.getParentFile()
        if (!viewParentDir.isDirectory()) {
            throw new Exception("Not a directory!")
        }
        def command = [scmCommand, 'rmview', '-force', viewPath + File.separator + viewName]
        CommandHelper tempCH = new CommandHelper(viewParentDir)
        tempCH.runCommand("Removing view : " + viewName, command)

        deleteViewDir()
    }


    protected void deleteViewDir() {
        if (directory.isDirectory()) {
            println "Deleting directory ${directory.absoluteFile} so it can be used for view creation"
            directory.deleteDir()
        }
    }

    protected void createView() {
        def command = [scmCommand, 'mkview']
        if (useTags) {
            command << '-tag' << viewName
        }
        command << '-snapshot'
        command << '-vws' << viewPath + File.separator + viewName
        
        if (streamName) {
            command << "-stream" << streamName + "@" + vobName
        }
        if (hostname) {
            command << '-host' << hostname
        }
        if (hostStorPath) {
            command << '-hpath' << hostStorPath
        }
        if (globStorPath) {
            command << '-gpath' << globStorPath
        }

        if (ptime) {
            command << '-ptime'
        }

        command << '-tmode' << tmode
        command << directory.getAbsolutePath()
        deleteViewDir()
        File viewParentDir = directory.getParentFile()
        if (viewParentDir == null) {
            throw new Exception("No Parent Directory for : " + directory.getAbsolutePath() + ":" + viewParentDir.getAbsolutePath())
        }
        if (!viewParentDir.isDirectory()) {
            throw new Exception("Not a directory!")
        }
        CommandHelper tempCH = new CommandHelper(viewParentDir)
        tempCH.runCommand("Creating view : " + viewName, command)
    }

    protected void populateVob(def target) {
        def command = [scmCommand, 'update', '-overwrite', '-force', "-add_loadrules"]
        if (target) {
            command << target
        }
        ch.runCommand("Populating with " + target, command)
    }
}
