// 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 XCTest
@testable import TulsiGenerator


class PBXObjectsTests: XCTestCase {
  enum ExpectedStructure {
    case fileReference(String)
    case group(String, contents: [ExpectedStructure])
  }

  var project: PBXProject! = nil

  override func setUp() {
    super.setUp()

    project = PBXProject(name: "TestProject")
  }

  // MARK: - Tests

  func testProjectCreateGroupsAndFileReferencesForPaths() {
    let paths = [
        "root",
        "test/file",
        "deeply/nested/files/1",
        "deeply/nested/files/2",
        "/empty/component",
    ]
    let expectedStructure: [ExpectedStructure] = [
        .fileReference("root"),
        .group("test", contents: [
            .fileReference("file"),
        ]),
        .group("deeply", contents: [
            .group("nested", contents: [
                .group("files", contents: [
                    .fileReference("1"),
                    .fileReference("2"),
                ]),
            ]),
        ]),
        .group("/", contents: [
            .group("empty", contents: [
                .fileReference("component"),
            ]),
        ]),
    ]

    project.getOrCreateGroupsAndFileReferencesForPaths(paths)
    assertProjectStructure(expectedStructure, forGroup: project.mainGroup)
  }

  func testProjectCreateGroupsAndFileReferencesForNoPathsIsNoOp() {
    let mainGroup: PBXGroup = project.mainGroup
    XCTAssertEqual(mainGroup.children.count, 0)
    project.getOrCreateGroupsAndFileReferencesForPaths([])
    XCTAssertEqual(mainGroup.children.count, 0)
  }

  func testProjectCreateGroupsAndFileReferencesForPathsMultiplePaths() {
    let paths1 = [
        "1",
        "unique/1",
        "overlapping/file"
    ]
    let paths2 = [
        "2",
        "unique/2",
        "overlapping/file",
        "overlapping/2"
    ]
    let expectedStructure: [ExpectedStructure] = [
        .fileReference("1"),
        .fileReference("2"),
        .group("unique", contents: [
            .fileReference("1"),
            .fileReference("2"),
        ]),
        .group("overlapping", contents: [
            .fileReference("file"),
            .fileReference("2"),
        ]),
    ]

    project.getOrCreateGroupsAndFileReferencesForPaths(paths1)
    project.getOrCreateGroupsAndFileReferencesForPaths(paths2)
    assertProjectStructure(expectedStructure, forGroup: project.mainGroup)
  }

  func testProjectCreateGroupsAndFileReferencesForBundlePath() {
    let paths = [
        "test",
        "bundle.xcassets/test_content",
        "subdir/test.app/file_inside",
        "subdir/test2.app/dir_inside/file_inside",
    ]
    let expectedStructure: [ExpectedStructure] = [
        .fileReference("test"),
        .fileReference("bundle.xcassets"),
        .group("subdir", contents: [
            .fileReference("test.app"),
            .fileReference("test2.app"),
        ]),
    ]

    project.getOrCreateGroupsAndFileReferencesForPaths(paths)
    assertProjectStructure(expectedStructure, forGroup: project.mainGroup)
  }

  func testSourceRelativePathGeneration() {
    let paths = [
        "1",
        "test/2",
        "deeply/nested/files/3",
        "deeply/nested/files/4"
    ]
    let expectedSourceRelativePaths = [
        "1": "1",
        "2": "test/2",
        "3": "deeply/nested/files/3",
        "4": "deeply/nested/files/4"
    ]
    project.getOrCreateGroupsAndFileReferencesForPaths(paths)
    for fileRef in project.mainGroup.allSources {
      let sourceRelativePath = fileRef.sourceRootRelativePath
      XCTAssertEqual(sourceRelativePath, expectedSourceRelativePaths[fileRef.path!])
    }
  }

  func testPBXReferenceFileExtension() {
    let filenameToExt: Dictionary<String, String?> = [
        "test.file": "file",
        "test": nil,
        "test.something.ext": "ext",
        "/someplace/test.something.ext": "ext",
    ]

    for (filename, ext) in filenameToExt {
      let f = PBXFileReference(name: "filename", path: filename, sourceTree: .Group, parent: nil)
      XCTAssertEqual(f.fileExtension, ext)

      let g = PBXGroup(name: "filename", path: filename, sourceTree: .Group, parent: nil)
      XCTAssertEqual(g.fileExtension, ext)
    }
  }

  func testPBXReferenceUTI() {
    let fileExtensionsToTest = [
        "a",
        "dylib",
        "swift",
        "xib",
    ]
    for ext in fileExtensionsToTest {
      let filename = "filename.\(ext)"
      let f = PBXFileReference(name: filename, path: filename, sourceTree: .Group, parent: nil)
      let expectedUTI = FileExtensionToUTI[ext]
      XCTAssertEqual(f.uti, expectedUTI, "UTI mismatch for extension '\(ext)'")

      let g = PBXGroup(name: filename, path: filename, sourceTree: .Group, parent: nil)
      XCTAssertEqual(g.uti, expectedUTI, "UTI mismatch for extension '\(ext)'")
    }

    let bundleExtensionsToTest = [
        "app",
        "bundle",
        "xcassets",
    ]
    for ext in bundleExtensionsToTest {
      let filename = "filename.\(ext)"
      let f = PBXFileReference(name: filename, path: filename, sourceTree: .Group, parent: nil)
      let expectedUTI = DirExtensionToUTI[ext]
      XCTAssertEqual(f.uti, expectedUTI, "UTI mismatch for extension '\(ext)'")

      let g = PBXGroup(name: filename, path: filename, sourceTree: .Group, parent: nil)
      XCTAssertEqual(g.uti, expectedUTI, "UTI mismatch for extension '\(ext)'")
    }
  }

  // MARK: - Helper methods

  func assertProjectStructure(_ expectedStructure: [ExpectedStructure],
                              forGroup group: PBXGroup,
                              line: UInt = #line) {
    XCTAssertEqual(group.children.count,
                   expectedStructure.count,
                   "Mismatch in child count for group '\(group.name)'",
                   line: line)

    for element in expectedStructure {
      switch element {
        case .fileReference(let name):
          assertGroup(group, containsSourceTree: .Group, path: name, line: line)

        case .group(let name, let grandChildren):
          let childGroup = assertGroup(group, containsGroupWithName: name, line: line)
          assertProjectStructure(grandChildren, forGroup: childGroup, line: line)
      }
    }
  }

  @discardableResult
  func assertGroup(_ group: PBXGroup,
                   containsSourceTree sourceTree: SourceTree,
                   path: String,
                   line: UInt = #line) -> PBXFileReference {
    let sourceTreePath = SourceTreePath(sourceTree: sourceTree, path: path)
    let fileRef = group.fileReferencesBySourceTreePath[sourceTreePath]
    XCTAssertNotNil(fileRef,
                    "Failed to find expected PBXFileReference '\(path)' in group '\(group.name)",
                    line: line)
    return fileRef!
  }

  func assertGroup(_ group: PBXGroup,
                   containsGroupWithName name: String,
                   line: UInt = #line) -> PBXGroup {
    let child = group.childGroupsByName[name]
    XCTAssertNotNil(child,
                    "Failed to find child group '\(name)' in group '\(group.name)'",
                    line: line)
    return child!
  }
}
