// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// RUN: %empty-directory(%t)
//
// RUN: %target-clang %S/Inputs/FoundationBridge/FoundationBridge.m -c -o %t/FoundationBridgeObjC.o -g
// RUN: %target-build-swift %s -I %S/Inputs/FoundationBridge/ -Xlinker %t/FoundationBridgeObjC.o -o %t/TestFileManager

// RUN: %target-run %t/TestFileManager > %t.txt
// REQUIRES: executable_test
// REQUIRES: objc_interop

import Foundation

#if FOUNDATION_XCTEST
import XCTest
class TestFileManagerSuper : XCTestCase { }
#else
import StdlibUnittest
class TestFileManagerSuper { }
#endif

class TestFileManager : TestFileManagerSuper {
    func testReplaceItem() {
        let fm = FileManager.default
        
        // Temporary directory
        let dirPath = (NSTemporaryDirectory() as NSString).appendingPathComponent(NSUUID().uuidString)
        try! fm.createDirectory(atPath: dirPath, withIntermediateDirectories: true, attributes: nil)
        defer { try! FileManager.default.removeItem(atPath: dirPath) }
        
        let filePath = (dirPath as NSString).appendingPathComponent("temp_file")
        try! "1".write(toFile: filePath, atomically: true, encoding: String.Encoding.utf8)
        
        let newItemPath = (dirPath as NSString).appendingPathComponent("temp_file_new")
        try! "2".write(toFile: newItemPath, atomically: true, encoding: String.Encoding.utf8)
        
        let result = try! fm.replaceItemAt(URL(fileURLWithPath:filePath, isDirectory:false), withItemAt:URL(fileURLWithPath:newItemPath, isDirectory:false))
        expectEqual(result!.path, filePath)
        
        let fromDisk = try! String(contentsOf: URL(fileURLWithPath:filePath, isDirectory:false), encoding: String.Encoding.utf8)
        expectEqual(fromDisk, "2")

    }
    
    func testReplaceItem_error() {
        let fm = FileManager.default
        
        // Temporary directory
        let dirPath = (NSTemporaryDirectory() as NSString).appendingPathComponent(NSUUID().uuidString)
        try! fm.createDirectory(atPath: dirPath, withIntermediateDirectories: true, attributes: nil)
        defer { try! FileManager.default.removeItem(atPath: dirPath) }
        
        let filePath = (dirPath as NSString).appendingPathComponent("temp_file")
        try! "1".write(toFile: filePath, atomically: true, encoding: String.Encoding.utf8)
        
        let newItemPath = (dirPath as NSString).appendingPathComponent("temp_file_new")
        // Don't write the file.
        
        var threw = false
        do {
            let _ = try fm.replaceItemAt(URL(fileURLWithPath:filePath, isDirectory:false), withItemAt:URL(fileURLWithPath:newItemPath, isDirectory:false))
        } catch {
            threw = true
        }
        expectTrue(threw, "Should have thrown")

    }
    
    func testDirectoryEnumerator_error() {
        let fm = FileManager.default
        let nonexistentURL = URL(fileURLWithPath: "\(NSTemporaryDirectory())/nonexistent")
        
        var invoked = false
        let e = fm.enumerator(at: nonexistentURL, includingPropertiesForKeys: []) { (url, err) in
            invoked = true
            expectEqual(nonexistentURL, url)
            expectEqual((err as NSError).code, NSFileReadNoSuchFileError)
            return true
        }

        let url = e?.nextObject()
        expectTrue(invoked)
        expectTrue(url == nil)
        
    }

    func testDirectoryEnumerator_error_noHandler() {
        let fm = FileManager.default
        let nonexistentURL = URL(fileURLWithPath: "\(NSTemporaryDirectory())/nonexistent")
        
        let e = fm.enumerator(at: nonexistentURL, includingPropertiesForKeys: [])
        let url = e?.nextObject()
        expectTrue(url == nil)
        
    }
    
    func testDirectoryEnumerator_simple() {
        let fm = FileManager.default
        let dirPath = (NSTemporaryDirectory() as NSString).appendingPathComponent(NSUUID().uuidString)
        try! fm.createDirectory(atPath: dirPath, withIntermediateDirectories: true, attributes: nil)
        defer { try! FileManager.default.removeItem(atPath: dirPath) }

        let item1 = URL(fileURLWithPath: "\(dirPath)/1", isDirectory: false)
        let item2 = URL(fileURLWithPath: "\(dirPath)/2", isDirectory: false)
        
        try! Data().write(to: item1)
        try! Data().write(to: item2)
        
        let e = fm.enumerator(at: URL(fileURLWithPath: dirPath, isDirectory: true), includingPropertiesForKeys: [])
        let result1 = e?.nextObject()
        let result2 = e?.nextObject()
        let result3 = e?.nextObject()
        
        // Avoid potential symlink discrepancy between the result and the original URL
        expectEqual((result1! as! URL).lastPathComponent, item1.lastPathComponent)
        expectEqual((result2! as! URL).lastPathComponent, item2.lastPathComponent)
        expectTrue(result3 == nil)
        
    }

}

#if !FOUNDATION_XCTEST
var FMTests = TestSuite("TestFileManager")
FMTests.test("testReplaceItem") { TestFileManager().testReplaceItem() }
FMTests.test("testReplaceItem_error") { TestFileManager().testReplaceItem_error() }
FMTests.test("testDirectoryEnumerator_error") { TestFileManager().testDirectoryEnumerator_error() }
FMTests.test("testDirectoryEnumerator_error_noHandler") { TestFileManager().testDirectoryEnumerator_error_noHandler() }
FMTests.test("testDirectoryEnumerator_simple") { TestFileManager().testDirectoryEnumerator_simple() }

runAllTests()
#endif

