import UIKit
import XCPlayground

enum Path: Equatable {
    
    case Current
    case Parent
    case Root
    case Letter(String)
}

extension Path: CustomStringConvertible {
    
    var description: String {
        switch self {
        case .Current:
            return "./"
        case .Parent:
            return "../"
        case .Root:
            return "/"
        case let .Letter(p):
            return p + "/"
        }
    }
}

func ==(lhs: Path, rhs: Path) -> Bool {
    
    switch lhs {
    case .Root:
        switch rhs {
        case .Root:
            return true
        default:
            return false
        }
    case .Parent:
        switch rhs {
        case .Parent:
            return true
        default:
            return false
        }
    case .Current:
        switch rhs {
        case .Current:
            return true
        default:
            return false
        }
    case let .Letter(letter):
        switch rhs {
        case let .Letter(retter):
            return letter == retter
        default:
            return false
        }
    }
}

struct URLExpression {
    
    private(set) var paths: [Path] = []
    
    init(path: String) {
        
        if path[path.startIndex] == "/" {
            self.paths.append(.Root)
        }
        
        for p in  (path.characters.split { $0 == "/" }) {
            let p = String(p)
            switch p {
            case ".":
                if self.paths.count == 0 {
                    self.paths.append(.Current)
                }
            case "..":
                if let last = self.paths.last {
                    switch last {
                    case .Parent:
                        self.paths.append(.Parent)
                    default:
                        self.paths.removeLast()
                    }
                } else {
                    self.paths.append(.Parent)
                }
            default:
                self.paths.append(.Letter(p))
            }
        }
        if self.paths.count == 0 {
            self.paths.append(.Current)
        }
    }
    
    init(url: NSURL) {
        
        if let path = url.path {
            let host = url.host ?? ""
            self.init(path: host + path)
        } else {
            self.init(path: "/")
        }
    }
    
    init() {
        
    }
}

extension URLExpression: SequenceType {
    
    var count: Int {
        return self.paths.count
    }
    
    var first: Path? {
        return self.paths.first
    }
    
    var last: Path? {
        return self.paths.last
    }
    
    subscript(idx: Int) -> Path {
        return self.paths[idx]
    }
    
    func generate() -> IndexingGenerator<[Path]> {
        return self.paths.generate()
    }
}

extension URLExpression {
    
    func traverseTo(to: URLExpression) -> URLExpression {
        
        var ret = URLExpression()
        
        if to[0] == .Root {
            var idx = 0
            for (i, (l, r)) in zip(self, to).enumerate() {
                print(i)
                if l == r {
                    idx++
                } else {
                    idx = i
                    break
                }
            }
            print(idx)
            for _ in self.paths[idx..<self.count] {
                ret.paths.append(.Parent)
            }
            if self.count == idx {
                ret.paths.append(.Current)
            }
            for p in to.paths[idx..<to.count] {
                switch p {
                case .Current:
                    break
                case .Root:
                    break
                default:
                    ret.paths.append(p)
                }
            }
        } else {
            ret.paths = self.paths
            for p in to {
                switch p {
                case .Parent:
                    if ret.last != .Root {
                        ret.paths.removeLast()
                    }
                case .Current:
                    break
                default:
                    ret.paths.append(p)
                }
            }
        }
        return ret
    }
}

extension URLExpression: CustomStringConvertible {
    
    var description: String {
        return self.paths.reduce("", combine: { i, p in
            i + p.description
        })
    }
}

let url = "ddd://dd/../../../../pp/./c/../.."
let uuu = NSURL(string: url)
uuu?.URLByStandardizingPath
uuu?.host
uuu?.path
let ex = URLExpression(url: NSURL(string: url)!)
ex.description



let from = URLExpression(path: "/Users/user/../Documents")
let to = URLExpression(path: "../../Users/user/../Documents")

let ret = from.traverseTo(to)
ret.description

to.traverseTo(from)