// LuhnAlgoEager benchmark
//
// Description: Performs a Luhn checksum eagerly
// Source: https://gist.github.com/airspeedswift/e584239d7658b317f59a

import TestsUtils

public var LuhnAlgoEager = BenchmarkInfo(
  name: "LuhnAlgoEager",
  runFunction: run_LuhnAlgoEager,
  tags: [.algorithm]
)

@inline(never)
public func run_LuhnAlgoEager(_ N: Int) {
    let resultRef = true
    var result = false

    for _ in 1...100*N {
        result = eagerchecksum(ccnum)

        if result != resultRef {
            break
        }
    }

    CheckResults(result == resultRef)
}

// Another version of the Luhn algorithm, similar to the one found here:
//   https://gist.github.com/airspeedswift/b349c256e90da746b852
//
// This time, trying to keep two versions, one eager one lazy,
// as similar as possible. Only adding "lazy" to the start of
// the expression to switch between the two.
//
// Much of the same code as the previous version at the top,
// Skip down to line 110 for the different par

// mapSome is my Swift version of Haskell's mapMaybe, which
// is a map that takes a transform function that returns an
// optional, and returns a collection of only those values
// that weren't nil

// first we need a lazy view that holds the original
// sequence and the transform function
struct MapSomeSequenceView<Base: Sequence, T> {
    fileprivate let _base: Base
    fileprivate let _transform: (Base.Iterator.Element) -> T?
}

// extend it to implement Sequence
extension MapSomeSequenceView: Sequence {
    typealias Iterator = AnyIterator<T>

    func makeIterator() -> Iterator {
        var g = _base.makeIterator()
        // AnyIterator is a helper that takes a
        // closure and calls it to generate each
        // element
        return AnyIterator {
            while let element = g.next() {
                if let some = self._transform(element) {
                    return some
                }
            }
            return nil
        }
    }
}

// now extend a lazy collection to return that view
// from a call to mapSome.  In pracice, when doing this,
// you should do it for all the lazy wrappers
// (i.e. random-access, forward and sequence)
extension LazyCollectionProtocol {
    // I might be missing a trick with this super-ugly return type, is there a
    // better way?
    func mapSome<U>(
        _ transform: @escaping (Elements.Iterator.Element) -> U?
    ) -> LazySequence<MapSomeSequenceView<Elements, U>> {
        return MapSomeSequenceView(_base: elements, _transform: transform).lazy
    }
}

// curried function - call with 1 argument to get a function
// that tells you if i is a multiple of a given number
// e.g.
//  let isEven = isMultipleOf(2)
//  isEven(4) // true
func isMultipleOf<T: FixedWidthInteger>(_ of: T)->(T)->Bool {
    return { $0 % of == 0 }
}

// extend LazySequence to map only every nth element, with all
// other elements untransformed.
extension LazySequenceProtocol {
  func mapEveryN(
    _ n: Int,
    _ transform: @escaping (Iterator.Element) -> Iterator.Element
  ) -> LazyMapSequence<EnumeratedSequence<Self>, Iterator.Element> {
    let isNth = isMultipleOf(n)
    func transform2(
      _ pair: EnumeratedSequence<Self>.Iterator.Element
    ) -> Iterator.Element {
      return isNth(pair.0 + 1) ? transform(pair.1) : pair.1
    }
    return self.enumerated().lazy.map(transform2)
  }
}

infix operator |> : PipeRightPrecedence
precedencegroup PipeRightPrecedence {
    associativity: left
}

func |><T,U>(t: T, f: (T)->U) -> U {
    return f(t)
}

infix operator • : DotPrecedence
precedencegroup DotPrecedence {
    associativity: left
}

func • <T, U, V> (g: @escaping (U) -> V, f: @escaping (T) -> U) -> (T) -> V {
    return { x in g(f(x)) }
}

// function to free a method from the shackles
// of it's owner
func freeMemberFunc<T,U>(_ f: @escaping (T)->()->U)->(T)->U {
    return { (t: T)->U in f(t)() }
}

extension String {
  func toInt() -> Int? { return Int(self) }
}

// stringToInt can now be pipelined or composed
let stringToInt = freeMemberFunc(String.toInt)
// if only Character also had a toInt method
let charToString = { (c: Character) -> String in String(c) }
let charToInt = stringToInt • charToString

func sum<S: Sequence>(_ nums: S)->S.Iterator.Element where S.Iterator.Element: FixedWidthInteger {
    return nums.reduce(0, +)
}

func reverse<C: LazyCollectionProtocol>(
    _ source: C
) -> LazyCollection<ReversedCollection<C.Elements>> {
  return source.elements.reversed().lazy
}

func map<S: LazySequenceProtocol, U>(
  _ source: S, _ transform: @escaping (S.Elements.Iterator.Element)->U
) -> LazyMapSequence<S.Elements,U> {
  return source.map(transform)
}

func mapSome<C: LazyCollectionProtocol, U>(
    _ source: C,
    _ transform: @escaping (C.Elements.Iterator.Element)->U?
) -> LazySequence<MapSomeSequenceView<C.Elements, U>> {
    return source.mapSome(transform)
}

func mapEveryN<S: LazySequenceProtocol>(
    _ source: S, _ n: Int,
    _ transform: @escaping (S.Iterator.Element)->S.Iterator.Element
) -> LazyMapSequence<EnumeratedSequence<S>, S.Iterator.Element> {
    return source.mapEveryN(n, transform)
}

// Non-lazy version of mapSome:
func mapSome<S: Sequence, C: RangeReplaceableCollection>(
    _ source: S,
    _ transform: @escaping (S.Iterator.Element)->C.Iterator.Element?
) -> C {
    var result = C()
    for x in source {
        if let y = transform(x) {
            result.append(y)
        }
    }
    return result
}

// Specialized default version of mapSome that returns an array, to avoid
// forcing the user having to specify:
func mapSome<S: Sequence,U>(
    _ source: S,
    _ transform: @escaping (S.Iterator.Element
)->U?)->[U] {
    // just calls the more generalized version
    return mapSome(source, transform)
}

// Non-lazy version of mapEveryN:
func mapEveryN<S: Sequence>(
    _ source: S, _ n: Int,
    _ transform: @escaping (S.Iterator.Element) -> S.Iterator.Element
) -> [S.Iterator.Element] {
    let isNth = isMultipleOf(n)
    return source.enumerated().map {
        (pair: (index: Int, elem: S.Iterator.Element)) in
        isNth(pair.index+1)
            ? transform(pair.elem)
            : pair.elem
    }
}

let double = { $0*2 }

let combineDoubleDigits = {
    (10...18).contains($0) ? $0-9 : $0
}

// removing lazy at start of pipeline
// switches to array-based version
let eagerchecksum = { (ccnum: String) -> Bool in
    ccnum //.lazy
    |> { $0.reversed().lazy }
    |> { mapSome($0, charToInt) }
    |> { mapEveryN($0, 2, double) }
    |> { map($0, combineDoubleDigits) }
    |> sum
    |> isMultipleOf(10)
}

let ccnum = "4012 8888 8888 1881"
