<commit_before>//
//  Listing.swift
//  NewHomzAPI
//
//  Created by stephenciauri on 4/8/17.
//
//

import Foundation
import PerfectLib
import PerfectHTTPServer
import MySQL
import Dispatch

class Listing: JSONConvertibleObject {
    static let sparseColumns: [String] = ["id", "listing", "photo", "active", "lat", "lng", "builderID", "priceTxt", "priceLow", "priceHigh", "sqftLow", "sqftHigh", "bedLow", "bedHigh", "bathLow", "bathHigh"]
    static let detailColumns: [String] = ["propType", "city", "county", "state", "zip", "description", "email", "website", "phone", "vid", "schoolDistrictName"]
    static let allColumns: [String] = sparseColumns + detailColumns
    
    private var sparseEntity: Bool = true
    
    // Sparse properties
    var id: Int = -1
    var name: String = "<null>"
    var builderId: Int = -1
    var status: Status = .inactive
    var featuredPhoto: URL?
    var coordinate: NSPoint = NSPoint(x: 0, y: 0)
    var priceText: String = "From the"
    var price: Range<Int> = Range(uncheckedBounds: (0,0))
    var squareFootage: Range<Int> = Range(uncheckedBounds: (0,0))
    var bedrooms: Range<Int> = Range(uncheckedBounds: (0,0))
    var bathrooms: Range<Float> = Range(uncheckedBounds: (0,0))
    
    // Detailed properties
    var builder: Builder?
    var description: String = ""
    var schoolDistrictName: String = ""
    var gallery: [Image] = []
    var floorplans: [Image] = []
    var propertyType: String = ""
    var email: String = ""
    var website: URL?
    var video: URL?
    var phone: String = ""

    enum Status: Int {
        case inactive
        case active
        case featured
        
        var jsonValue: String {
            switch self {
            case .inactive:
                return "INACTIVE"
            case .active:
                return "ACTIVE"
            case .featured:
                return "FEATURED"
            }
        }
    }

    init(withSparseResult result: [String:String]) {
        super.init()
        id = result["id"]?.intValue ?? id
        builderId = result["builderID"]?.intValue ?? builderId
        name = result["listing"] ?? name
        priceText = result["priceText"] ?? priceText
        featuredPhoto = result["photo"]?.urlValue ?? featuredPhoto

        if
            let lat = result["lat"]?.doubleValue,
            let long = result["lng"]?.doubleValue {
            coordinate = NSPoint(x: CGFloat(lat) , y: CGFloat(long))
        }
        
        if
            let priceLow = result["priceLow"]?.intValue,
            let priceHigh = result["priceHigh"]?.intValue {
            price = Range(uncheckedBounds: (priceLow, priceHigh))
        }
        
        if
            let squareFootLow = result["sqftLow"]?.intValue,
            let squareFootHigh = result["sqftHigh"]?.intValue {
            squareFootage = Range(uncheckedBounds: (squareFootLow, squareFootHigh))
        }
        
        if
            let bedLow = result["bedLow"]?.intValue,
            let bedHigh = result["bedHigh"]?.intValue {
            bedrooms = Range(uncheckedBounds: (bedLow, bedHigh))
        }
        
        if
            let bathLow = result["bathLow"]?.floatValue,
            let bathHigh = result["bathHigh"]?.floatValue {
            bathrooms = Range(uncheckedBounds: (bathLow, bathHigh))
        }
        
        if
            let statusInt = result["active"]?.intValue,
            let status = Status(rawValue: statusInt) {
            self.status = status
        }
    }
    
    
    convenience init(withResult result: [String:String]) {
        self.init(withSparseResult: result)
        sparseEntity = false
        propertyType = result["propType"] ?? propertyType
        description = result["description"] ?? description
        email = result["email"] ?? email
        website = result["website"]?.urlValue ?? website
        phone = result["phone"] ?? phone
        video = result["vid"]?.urlValue ?? video
        schoolDistrictName = result["schoolDistrictName"] ?? schoolDistrictName
    }
    
    override func getJSONValues() -> [String : Any] {
        var json: [String:Any] = [
            "id": id,
            "href": href ?? "",
            "links": links,
            "name": name,
            "builderID": builderId,
            "coordinate": ["latitude":Double(coordinate.x), "longitude":Double(coordinate.y)],
            "price": ["min":price.lowerBound, "max":price.upperBound],
            "priceText": priceText,
            "squareFootage": ["min":squareFootage.lowerBound, "max":squareFootage.upperBound],
            "bedrooms": ["min":bedrooms.lowerBound, "max":bedrooms.upperBound],
            "bathrooms": ["min":Double(bathrooms.lowerBound), "max":Double(bathrooms.upperBound)],
            "status": status.jsonValue
        ]
        
        if let featuredPhoto = featuredPhoto {
            json["featuredPhoto"] = featuredPhoto
        }

        if !sparseEntity {
            if let builder = builder {
                json["builder"] = builder
            }
            let extendedFields: [String:Any] = [
                "gallery": gallery,
                "floorplans": floorplans,
                "description": description,
                "schoolDistrictName": schoolDistrictName,
                "propertyType": propertyType,
                "email": email,
                "phone": phone
            ]
            
            if let website = website {
                json["website"] = website
            }
            if let video = video {
                json["video"] = video
            }
            
            json += extendedFields
        }
        return json
    }
}

extension Listing: RESTEntity {
    var href: URL? {
        return ListingResource.idRoute.absoluteURLString.replacingOccurrences(of: "{id}", with: "\(id)").urlValue!<commit_msg>Add demographic information to detailed listing view<commit_after>//
//  Listing.swift
//  NewHomzAPI
//
//  Created by stephenciauri on 4/8/17.
//
//

import Foundation
import PerfectLib
import PerfectHTTPServer
import MySQL
import Dispatch

class Listing: JSONConvertibleObject {
    static let sparseColumns: [String] = ["id", "listing", "photo", "active", "lat", "lng", "builderID", "priceTxt", "priceLow", "priceHigh", "sqftLow", "sqftHigh", "bedLow", "bedHigh", "bathLow", "bathHigh"]
    static let detailColumns: [String] = ["propType", "city", "county", "state", "zip", "description", "email", "website", "phone", "vid", "schoolDistrictName"]
    static let allColumns: [String] = sparseColumns + detailColumns
    
    private var sparseEntity: Bool = true
    
    // Sparse properties
    var id: Int = -1
    var name: String = "<null>"
    var builderId: Int = -1
    var status: Status = .inactive
    var featuredPhoto: URL?
    var coordinate: NSPoint = NSPoint(x: 0, y: 0)
    var priceText: String = "From the"
    var price: Range<Int> = Range(uncheckedBounds: (0,0))
    var squareFootage: Range<Int> = Range(uncheckedBounds: (0,0))
    var bedrooms: Range<Int> = Range(uncheckedBounds: (0,0))
    var bathrooms: Range<Float> = Range(uncheckedBounds: (0,0))
    
    // Detailed properties
    var builder: Builder?
    var description: String = ""
    var schoolDistrictName: String = ""
    var gallery: [Image] = []
    var floorplans: [Image] = []
    var propertyType: String = ""
    var email: String = ""
    var website: URL?
    var video: URL?
    var phone: String = ""
    var city: String = ""
    var county: String = ""
    var state: String = ""
    var zip: String = ""

    enum Status: Int {
        case inactive
        case active
        case featured
        
        var jsonValue: String {
            switch self {
            case .inactive:
                return "INACTIVE"
            case .active:
                return "ACTIVE"
            case .featured:
                return "FEATURED"
            }
        }
    }

    init(withSparseResult result: [String:String]) {
        super.init()
        id = result["id"]?.intValue ?? id
        builderId = result["builderID"]?.intValue ?? builderId
        name = result["listing"] ?? name
        priceText = result["priceText"] ?? priceText
        featuredPhoto = result["photo"]?.urlValue ?? featuredPhoto

        if
            let lat = result["lat"]?.doubleValue,
            let long = result["lng"]?.doubleValue {
            coordinate = NSPoint(x: CGFloat(lat) , y: CGFloat(long))
        }
        
        if
            let priceLow = result["priceLow"]?.intValue,
            let priceHigh = result["priceHigh"]?.intValue {
            price = Range(uncheckedBounds: (priceLow, priceHigh))
        }
        
        if
            let squareFootLow = result["sqftLow"]?.intValue,
            let squareFootHigh = result["sqftHigh"]?.intValue {
            squareFootage = Range(uncheckedBounds: (squareFootLow, squareFootHigh))
        }
        
        if
            let bedLow = result["bedLow"]?.intValue,
            let bedHigh = result["bedHigh"]?.intValue {
            bedrooms = Range(uncheckedBounds: (bedLow, bedHigh))
        }
        
        if
            let bathLow = result["bathLow"]?.floatValue,
            let bathHigh = result["bathHigh"]?.floatValue {
            bathrooms = Range(uncheckedBounds: (bathLow, bathHigh))
        }
        
        if
            let statusInt = result["active"]?.intValue,
            let status = Status(rawValue: statusInt) {
            self.status = status
        }
    }
    
    
    convenience init(withResult result: [String:String]) {
        self.init(withSparseResult: result)
        sparseEntity = false
        propertyType = result["propType"] ?? propertyType
        description = result["description"] ?? description
        email = result["email"] ?? email
        website = result["website"]?.urlValue ?? website
        phone = result["phone"] ?? phone
        video = result["vid"]?.urlValue ?? video
        schoolDistrictName = result["schoolDistrictName"] ?? schoolDistrictName
        city = result["city"] ?? city
        county = result["county"] ?? county
        state = result["state"] ?? state
        zip = result["zip"] ?? zip
    }
    
    override func getJSONValues() -> [String : Any] {
        var json: [String:Any] = [
            "id": id,
            "href": href ?? "",
            "links": links,
            "name": name,
            "builderID": builderId,
            "coordinate": ["latitude":Double(coordinate.x), "longitude":Double(coordinate.y)],
            "price": ["min":price.lowerBound, "max":price.upperBound],
            "priceText": priceText,
            "squareFootage": ["min":squareFootage.lowerBound, "max":squareFootage.upperBound],
            "bedrooms": ["min":bedrooms.lowerBound, "max":bedrooms.upperBound],
            "bathrooms": ["min":Double(bathrooms.lowerBound), "max":Double(bathrooms.upperBound)],
            "status": status.jsonValue
        ]
        
        if let featuredPhoto = featuredPhoto {
            json["featuredPhoto"] = featuredPhoto
        }

        if !sparseEntity {
            if let builder = builder {
                json["builder"] = builder
            }
            let extendedFields: [String:Any] = [
                "gallery": gallery,
                "floorplans": floorplans,
                "description": description,
                "schoolDistrictName": schoolDistrictName,
                "propertyType": propertyType,
                "email": email,
                "phone": phone,
                "city": city,
                "county": county,
                "state": state,
                "zip":zip
            ]
            
            if let website = website {
                json["website"] = website
            }
            if let video = video {
                json["video"] = video
            }
            
            json += extendedFields
        }
        return json
    }
}

extension Listing: RESTEntity {
    var href: URL? {
        return ListingResource.idRoute.absoluteURLString.replacingOccurrences(of: "{id}", with: "\(id)").urlValue!
{'fraction_non_alphanumeric': 0.1261335531739489, 'fraction_numerical': 0.0026380873866446827, 'mean_word_length': 2.014662027833002, 'pattern_counts': {'":': 62, '<': 13, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1265719', 'n_tokens_mistral': 3388, 'n_tokens_neox': 3297, 'n_words': 810}