// Copyright 2016 The Tulsi Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Foundation


/// Provides functionality to generate an Xcode project from a TulsiGeneratorConfig.
public final class TulsiXcodeProjectGenerator {

  public enum GeneratorError: Error {
    /// General Xcode project creation failure with associated debug info.
    case serializationFailed(String)
    /// The project config included an entry with the associated unsupported type.
    case unsupportedTargetType(String, String)
  }

  public static let ScriptDirectorySubpath = XcodeProjectGenerator.ScriptDirectorySubpath
  public static let ConfigDirectorySubpath = XcodeProjectGenerator.ConfigDirectorySubpath

  let xcodeProjectGenerator: XcodeProjectGenerator

  public convenience init (workspaceRootURL: URL,
                           config: TulsiGeneratorConfig,
                           tulsiVersion: String) {
    self.init(workspaceRootURL: workspaceRootURL,
              config: config,
              extractorBazelURL: config.bazelURL as URL,
              tulsiVersion: tulsiVersion)
  }

  init(workspaceRootURL: URL,
       config: TulsiGeneratorConfig,
       extractorBazelURL: URL,
       tulsiVersion: String) {
    let bundle = Bundle(for: type(of: self))
    let localizedMessageLogger = LocalizedMessageLogger(bundle: bundle)

    let resourceURLs = XcodeProjectGenerator.ResourceSourcePathURLs(
        buildScript: bundle.url(forResource: "bazel_build", withExtension: "py")!,
        resignerScript: bundle.url(forResource: "resigner", withExtension: "py")!,
        cleanScript: bundle.url(forResource: "bazel_clean", withExtension: "sh")!,
        extraBuildScripts: [bundle.url(forResource: "tulsi_logging", withExtension: "py")!,
                            bundle.url(forResource: "bazel_options", withExtension: "py")!,
                            bundle.url(forResource: "apfs_clone_copy", withExtension: "py")!,
                            bundle.url(forResource: "bazel_build_events", withExtension: "py")!,
                            bundle.url(forResource: "bootstrap_lldbinit", withExtension: "py")!,
                            bundle.url(forResource: "symbol_cache_schema", withExtension: "py")!,
                            bundle.url(forResource: "update_symbol_cache", withExtension: "py")!,
                            bundle.url(forResource: "install_genfiles", withExtension: "py")!,
                            bundle.url(forResource: "user_build", withExtension: "py")!],
        iOSUIRunnerEntitlements: bundle.url(forResource: "iOSXCTRunner", withExtension: "entitlements")!,
        macOSUIRunnerEntitlements: bundle.url(forResource: "macOSXCTRunner", withExtension: "entitlements")!,
        stubInfoPlist: bundle.url(forResource: "StubInfoPlist", withExtension: "plist")!,
        stubIOSAppExInfoPlistTemplate: bundle.url(forResource: "StubIOSAppExtensionInfoPlist", withExtension: "plist")!,
        stubWatchOS2InfoPlist: bundle.url(forResource: "StubWatchOS2InfoPlist", withExtension: "plist")!,
        stubWatchOS2AppExInfoPlist: bundle.url(forResource: "StubWatchOS2AppExtensionInfoPlist", withExtension: "plist")!,
        stubClang: bundle.url(forResource: "clang_stub", withExtension: "sh")!,
        stubSwiftc: bundle.url(forResource: "swiftc_stub", withExtension: "py")!,
        stubLd: bundle.url(forResource: "ld_stub", withExtension: "sh")!,
        bazelWorkspaceFile: bundle.url(forResource: "WORKSPACE", withExtension: nil)!,
        tulsiPackageFiles: bundle.urls(forResourcesWithExtension: nil, subdirectory: "tulsi")!)

    // Note: A new extractor is created on each generate in order to allow users to modify their
    // BUILD files (or add new files to glob's) and regenerate without restarting Tulsi.
    let extractor = BazelWorkspaceInfoExtractor(bazelURL: extractorBazelURL,
                                                workspaceRootURL: workspaceRootURL,
                                                localizedMessageLogger: localizedMessageLogger,
                                                runAspectsFromWorkspace: config.options.runAspectsFromWorkspace)

    xcodeProjectGenerator = XcodeProjectGenerator(workspaceRootURL: workspaceRootURL,
                                                  config: config,
                                                  localizedMessageLogger: localizedMessageLogger,
                                                  workspaceInfoExtractor: extractor,
                                                  resourceURLs: resourceURLs,
                                                  tulsiVersion: tulsiVersion)
  }

  /// Generates an Xcode project bundle in the given folder.
  /// NOTE: This may be a long running operation.
  public func generateXcodeProjectInFolder(
    _ outputFolderURL: URL) throws -> URL {
    do {
      return try xcodeProjectGenerator.generateXcodeProjectInFolder(
        outputFolderURL)
    } catch let e {
      LogMessage.postError("Project generation failed.")
      xcodeProjectGenerator.logPendingMessages()
      switch e {
      case PBXTargetGenerator.ProjectSerializationError.unsupportedTargetType(let targetType,
                                                                              let label):
        throw GeneratorError.unsupportedTargetType(targetType, label)
      case PBXTargetGenerator.ProjectSerializationError.generalFailure(let info):
        throw GeneratorError.serializationFailed(info)
      case XcodeProjectGenerator.ProjectGeneratorError.serializationFailed(let info):
        throw GeneratorError.serializationFailed(info)
      case XcodeProjectGenerator.ProjectGeneratorError.labelAspectFailure(let info):
        throw GeneratorError.serializationFailed(info)
      case XcodeProjectGenerator.ProjectGeneratorError.labelResolutionFailed(let labels):
        throw GeneratorError.serializationFailed("Failed to resolve labels: \(labels)")
      case XcodeProjectGenerator.ProjectGeneratorError.invalidXcodeProjectPath(let path,
                                                                               let reason):
        throw GeneratorError.serializationFailed("Xcode project cannot be generated in " +
            "\(path) because it lies within \(reason).")
      case let e as NSError:
        throw GeneratorError.serializationFailed("Unexpected exception \(e.localizedDescription)")
      default:
        throw GeneratorError.serializationFailed("Unexpected exception \(e)")
      }
    }
  }
}
