// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package os

import 

// fastrand provided by runtime.
// We generate random temporary file names so that there's a good
// chance the file doesn't exist yet - keeps the number of tries in
// TempFile to a minimum.
func fastrand() uint32

func nextRandom() string {
	return uitoa(uint(fastrand()))
}

// CreateTemp creates a new temporary file in the directory dir,
// opens the file for reading and writing, and returns the resulting file.
// The filename is generated by taking pattern and adding a random string to the end.
// If pattern includes a "*", the random string replaces the last "*".
// If dir is the empty string, CreateTemp uses the default directory for temporary files, as returned by TempDir.
// Multiple programs or goroutines calling CreateTemp simultaneously will not choose the same file.
// The caller can use the file's Name method to find the pathname of the file.
// It is the caller's responsibility to remove the file when it is no longer needed.
func (,  string) (*File, error) {
	if  == "" {
		 = TempDir()
	}

	, ,  := prefixAndSuffix()
	if  != nil {
		return nil, &PathError{Op: "createtemp", Path: , Err: }
	}
	 = joinPath(, )

	 := 0
	for {
		 :=  + nextRandom() + 
		,  := OpenFile(, O_RDWR|O_CREATE|O_EXCL, 0600)
		if IsExist() {
			if ++;  < 10000 {
				continue
			}
			return nil, &PathError{Op: "createtemp", Path:  + string(PathSeparator) +  + "*" + , Err: ErrExist}
		}
		return , 
	}
}

var errPatternHasSeparator = errors.New("pattern contains path separator")

// prefixAndSuffix splits pattern by the last wildcard "*", if applicable,
// returning prefix as the part before "*" and suffix as the part after "*".
func prefixAndSuffix( string) (,  string,  error) {
	for  := 0;  < len(); ++ {
		if IsPathSeparator([]) {
			return "", "", errPatternHasSeparator
		}
	}
	if  := lastIndex(, '*');  != -1 {
		,  = [:], [+1:]
	} else {
		 = 
	}
	return , , nil
}

// MkdirTemp creates a new temporary directory in the directory dir
// and returns the pathname of the new directory.
// The new directory's name is generated by adding a random string to the end of pattern.
// If pattern includes a "*", the random string replaces the last "*" instead.
// If dir is the empty string, MkdirTemp uses the default directory for temporary files, as returned by TempDir.
// Multiple programs or goroutines calling MkdirTemp simultaneously will not choose the same directory.
// It is the caller's responsibility to remove the directory when it is no longer needed.
func (,  string) (string, error) {
	if  == "" {
		 = TempDir()
	}

	, ,  := prefixAndSuffix()
	if  != nil {
		return "", &PathError{Op: "mkdirtemp", Path: , Err: }
	}
	 = joinPath(, )

	 := 0
	for {
		 :=  + nextRandom() + 
		 := Mkdir(, 0700)
		if  == nil {
			return , nil
		}
		if IsExist() {
			if ++;  < 10000 {
				continue
			}
			return "", &PathError{Op: "mkdirtemp", Path:  + string(PathSeparator) +  + "*" + , Err: ErrExist}
		}
		if IsNotExist() {
			if ,  := Stat(); IsNotExist() {
				return "", 
			}
		}
		return "", 
	}
}

func joinPath(,  string) string {
	if len() > 0 && IsPathSeparator([len()-1]) {
		return  + 
	}
	return  + string(PathSeparator) + 
}

// LastIndexByte from the strings package.
func lastIndex( string,  byte) int {
	for  := len() - 1;  >= 0; -- {
		if [] ==  {
			return 
		}
	}
	return -1
}