package bridge

import (
	
	
	
	
	
	
	
	

	
	
	
	
	
	
	
)

type Session struct {
	SSH            *ssh.Client
	SSHSession     *ssh.Client
	SFTP           *sftp.Client
	SMB            *smb2.Session
	WinRM          *winrm.Client
	LastConnection time.Time
	WindowsLetter  string
	WindowsPath    string
	Username       string
	IpAddr         string
	Port           string
	password       string

	sync.Mutex
}

// CloseAllConnections closes all connections on session
func ( *Session) () {
	if .SSH != nil {
		 := .SSH.Close()
		if  != nil {
			logger.Sugar().Warnw("cannot close ssh session")
		}
	}

	if .SFTP != nil {
		 := .SFTP.Close()
		if  != nil {
			logger.Sugar().Warnw("cannot close sftp session")
		}
	}

	if .SMB != nil {
		 := .SMB.Logoff()
		if  != nil {
			logger.Sugar().Warnw("cannot close smb session")
		}
	}
}

// checkOutput watches for sudo output and inserts password if exists
func ( *Session) ( io.Writer,  *bytes.Buffer) bool {
	.Mutex.Lock()
	defer .Mutex.Unlock()
	if  != nil && .Len() > 0 && strings.Contains(.String(), "liman-pass-sudo") {
		,  := .Write([]byte(.password + "\n"))
		if  != nil {
			logger.Sugar().Warnw("cannot write sudo password")
			return false
		}
		return true
	}
	return false
}

// Run runs command on sessions SSH and returns output
func ( *Session) ( string) (string, error) {
	if .SSH != nil {
		,  := .SSH.NewSession()
		if  != nil {
			return "", 
		}
		defer .Close()
		 := ssh.TerminalModes{
			ssh.ECHO:          0,
			ssh.TTY_OP_ISPEED: 14400,
			ssh.TTY_OP_OSPEED: 14400,
		}
		 = .RequestPty("dumb", 1000, 1000, )
		if  != nil {
			return "", 
		}
		 := new(bytes.Buffer)
		.Stdout = 
		,  := .StdinPipe()
		if  != nil {
			return "", 
		}
		if strings.Contains(, "liman-pass-sudo") {
			 := make(chan struct{})
			defer close()
			go func( io.Writer,  *bytes.Buffer,  chan struct{}) {
			:
				for {
					select {
					case <-time.After(20 * time.Second):
					case <-:
						break 
					default:
						if .checkOutput(, ) {
							break 
						}

						time.Sleep(500)
					}
				}
			}(, , )
		}
		 = .Run("(" +  + ") 2> /dev/null")
		if  != nil {
			return .Error(), 
		}

		 := strings.Split(.String(), "liman-pass-sudo")
		 := [len()-1]

		return stripansi.Strip(strings.TrimSpace()), nil
	} else if .WinRM != nil {
		 = "$ProgressPreference = 'SilentlyContinue';" + 
		 := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
		,  := .String()
		 = base64.StdEncoding.EncodeToString([]byte())
		, , ,  := .WinRM.RunWithContextWithString(context.TODO(), "powershell.exe -encodedCommand "+, "")
		if  != nil {
			return "", 
		}
		return strings.TrimSpace() + strings.TrimSpace(), nil
	}
	return "", errors.New("cannot run command")
}