//

// USE THIS VERSION OF BundleUtilities

//

// Any versions not found in lib/swift might be oudated or unchecked

//

//  BundleUtilities.swift

//

//  Last modified Feb. 21 2107

//  Last modified 18. 4. 2017 (using @available to allow for macOS/iOS validity)

//  Now correctly produces deep listings; the way to find out whether a file 

// is a directory is the one used here. Do not trust hasDirectoryPath

//

import Foundation


public let dfm = FileManager.default


@available(macOS 10, *)


func homeURL() -> URL {

  

  return dfm.urls(for: FileManager.SearchPathDirectory.userDirectory,

                  in: FileManager.SearchPathDomainMask.userDomainMask).first!

  

}


@available (macOS 10, *)

func homePath() -> String {

  return homeURL().path

}



public func tmpURL() -> URL {

  if #available(iOS 10.0, *) {

    return dfm.temporaryDirectory

  } else {

    // Fallback on earlier versions

    return URL(string: NSTemporaryDirectory())!

  }

}


public func tmpPath() -> String{

  return tmpURL().path

}


public func documentsURL() -> URL {

  return dfm.urls(for: FileManager.SearchPathDirectory.documentDirectory,

                  in: FileManager.SearchPathDomainMask.userDomainMask).first!

}


public func documentsPath() -> String {

  return documentsURL().path

}


public func libraryURL() -> URL {

  return dfm.urls(for: FileManager.SearchPathDirectory.libraryDirectory,

                  in: FileManager.SearchPathDomainMask.userDomainMask).first!

  

}


public func libraryPath() -> String {

  return libraryURL().path

}

//

// Check whether a path or URL is directory or not

//

public func isDirectory(url: URL) -> Bool {

  var isDir: ObjCBool = false;

  dfm.fileExists(atPath: url.path, isDirectory: &isDir)

  return isDir.boolValue;

}


public func isDirectory(path: String) -> Bool {

  var isDir: ObjCBool = false;

  dfm.fileExists(atPath: path, isDirectory: &isDir)

  return isDir.boolValue;

}



public func readAsStringFromVirtualFolder(fileName:String, withExtension fileExtension:String) -> String? {

  var text:String?

  //

  // If the file is not found in the bundle, the string

  // given back by this method will be nil

  //

  guard  

    let temp = Bundle.main.url(forResource: fileName,

                               withExtension: fileExtension),

    !temp.hasDirectoryPath

    else { return nil }

  //

  // If we get here,there IS a file in the bundle with that name

  //

  do {

    text = try String(contentsOf: temp)

  } catch {

    text = nil

  }

  

  return text

} // End of readFromVirtualFolder()


public func readAsStringFromFolder(folderName:String,

                                   fileName:String, 

                                   withExtension fileExtension:String) -> String? {

  var text:String? = nil

  

  if let temp = Bundle.main.url(forResource: fileName,

                                withExtension: fileExtension,

                                subdirectory: folderName) {

    do {

      text = try String(contentsOf: temp)

    } catch  {

      text = nil

    } // End of do/catch

    

  } // End of if/let

  return text

} // End of readFromFolder(folderName:)



public func listingOfBundle() -> String? {

  var text = ""

  

  //

  // MAIN ACCESS METHOD - URLs OF ITEMS IN BUNDLE

  //

  if let itemURLs = Bundle.main.urls(forResourcesWithExtension: nil,

                                     subdirectory: nil) {

    print(itemURLs)

    itemURLs.forEach() {

      text.append( (isDirectory(url: $0) ? "Directory : " : "File      : ")

        + "\($0.lastPathComponent)"

        + "\n")

    } // End of forEach

    

  } // End of if let

  

  return text

  

} // End of listingOfBundle()


public func listingOfDirectory(_ url:URL) -> String? {

  print("Directory under consideration: \(url)")

  let nameOfSubdirectory = url.lastPathComponent

  var text = ""

  let directoryContents = Bundle.main.urls(forResourcesWithExtension: nil, subdirectory: nameOfSubdirectory)

  print("adding contents of \(nameOfSubdirectory)")

  directoryContents?.forEach() {

    if isDirectory(url: $0) {

      text.append(listingOfDirectory($0)! + "\n")

    } else {

      text.append($0.lastPathComponent + "\n")

    }

  }

  return text

}

public func deepListingOfBundle() -> String? {

  var text = ""

  

  //

  // MAIN ACCESS METHOD - URLs OF ALL ITEMS IN BUNDLE

  //

  if let itemURLs = Bundle.main.urls(forResourcesWithExtension: nil,

                                     subdirectory: nil) {

    

    itemURLs.forEach() {

      if isDirectory(url: $0) {

        text.append("Directory: \($0.lastPathComponent):\n")

        text.append(listingOfDirectory($0)!)

      } else {

        text.append( ("File      : ")

          + "\($0.lastPathComponent)"

          + "\n")

      }

    } // End of forEach

    

  } // End of if let

  

  return text

  

  

} // End of deepListingOfBundle()


func deepListingOfDirectoriesInBundle() -> String? {

  var text = ""

  if  let bundleResourceURL = Bundle.main.resourceURL {

    

    if let itemURLs =   dfm.enumerator(at:  bundleResourceURL,

                                       includingPropertiesForKeys: []) {

      itemURLs.forEach() {

        let url = $0 as! URL

        if isDirectory(url: url) {

          text.append( url.absoluteString

            + "\n\n")

        }

      }

    } // End of forEach

    

  } // End of if let

  

  return text

} // End of deepListingOfDirectoriesInBundle()


func listingOfFilesInBundle(withExtension fileExtension:String) -> String? {

  var text = ""

  guard

    let itemURLs =   Bundle.main.urls(forResourcesWithExtension: fileExtension,

                                      subdirectory:nil)

    else {

      text = "Could not create list of typed URLs in bundle"

      return text

  } // End of guard

  if itemURLs.isEmpty {

    text = "No files with .jpg extension found in bundle"

  }

  itemURLs.forEach() { text.append( $0.absoluteString + "\n\n") }

  return text

} // End of listingOfFilesInBundle(withType:)



// This method shows the list of resources with a given extension

// that are stored inside a folder in the bundle

//

// Do realize that a relative path into that folder is easy to build

// and lets the programmer access any file of a given type inside

// a given folder in the bundle, even when the final parent folder

// is nested 3 deep into the topmost one.

//

// In other words, folder denotes folder_path

//

func listingOfBundleFileIn(folder:String,

                           withExtension fileExtension:String) -> String? {

  var text = ""

  //

  // Just write the path to the subdirectory (folder media_blue) in the second argument

  //

  guard

    let itemURLs =   Bundle.main.urls(forResourcesWithExtension: fileExtension,

                                      subdirectory: folder)

    else {

      text = "Could not create list of URLs for types resources in subdirectory media_blue"

      return text

  } // End of guard

  if itemURLs.isEmpty {

    text = "No .png files to show in directory media_blue"

  }

  itemURLs.forEach() { text.append( $0.absoluteString + "\n\n") }

  return text

}