//
//  TransactionSigningTests.swift
//  Zesame
//
//  Created by Alexander Cyon on 2018-09-11.
//  Copyright © 2018 Open Zesame. All rights reserved.
//

import XCTest
import EllipticCurveKit
@testable import Zesame

//extension Zesame.Wallet {
//
////    init(keyPair: KeyPair, network: Network) {
////        self.init(keyPair: keyPair, address:  Address(keyPair: keyPair, network: network))
////    }
//
//    init?(privateKeyHex: String, network: Network = .default) {
//        guard let keyPair = KeyPair(privateKeyHex: privateKeyHex) else { return nil }
////        self.init(keyPair: keyPair, network: network)
//        let keystore
//        self.init(keystore: <#T##Keystore#>, address: <#T##Address#>)
//    }
//}

// Some uninteresting Zilliqa TESTNET private key, containing worthless TEST tokens.
private let privateKeyHex = "0E891B9DFF485000C7D1DC22ECF3A583CC50328684321D61947A86E57CF6C638"
//private let wallet = Wallet(privateKeyHex: privateKey)  //Wallet(privateKeyHex: privateKey, balance: 100000, nonce: 3)!
private let service = DefaultZilliqaService.shared


class TransactionSigningTests: XCTestCase {

    func testTransactionSigning() {
//        XCTAssertEqual(wallet.keyPair.publicKey.hex.compressed.lowercased(), "034ae47910d58b9bde819c3cffa8de4441955508db00aa2540db8e6bf6e99abc1b")

        let privateKey = PrivateKey(hex: privateKeyHex)!
        let publicKey = PublicKey(privateKey: privateKey)
        let keyPair = KeyPair(privateKeyHex: privateKeyHex)!

        let recipient = try! Address(hexString: "9CA91EB535FB92FDA5094110FDAEB752EDB9B039")

        let payment = Payment(
            to: recipient,
            amount: 15,
            gasLimit: 1,
            gasPrice: 1,
            nonce: Nonce(3)
        )!

        let unsignedTx = UnsignedTransaction(payment: payment, version: 0)

        XCTAssertEqual(unsignedTx.amount, 15)
        XCTAssertEqual(unsignedTx.gasLimit, 1)
        XCTAssertEqual(unsignedTx.gasPrice, 1)
        XCTAssertEqual(unsignedTx.nonce, 4)
        XCTAssertEqual(unsignedTx.version, 0)
        XCTAssertEqual(unsignedTx.to, "9cA91eB535fb92FDA5094110fDAeb752EdB9B039")

        let message = messageFromUnsignedTransaction(unsignedTx, publicKey: publicKey)

        XCTAssertEqual(message.description.lowercased(), "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049CA91EB535FB92FDA5094110FDAEB752EDB9B039034ae47910d58b9bde819c3cffa8de4441955508db00aa2540db8e6bf6e99abc1b000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000".lowercased())

        let signature = service.sign(message: message, using: keyPair)

        // Generated by https://github.com/Zilliqa/Zilliqa-JavaScript-Library/commit/3a4566138def7d622b0bbc331186ce7d2b8c465c
        let expectedSignature = "BB32937FE38FAEB28968A4B346D8DBBCE22228AE0399B32C29B370C65417A7724AF3E392CDF251D9E51803D56C0D98AC38B4346B7151D0A59F6F31376B2E025F"

        XCTAssertEqual(signature.asHexString(), expectedSignature)

        func signatureForManipulatedMessage(onlyUppercased shouldUppercase: Bool) -> String {
            let msg = message.description
            let manipulatedRaw = shouldUppercase ? msg.uppercased() : msg.lowercased()
            let manipulated = Message(hashedHex: manipulatedRaw, hashedBy: EllipticCurveKit.DefaultHasher.sha256)!
            return service.sign(message: manipulated, using: keyPair).asHexString()
        }

        XCTAssertEqual(signatureForManipulatedMessage(onlyUppercased: true), expectedSignature)
        XCTAssertEqual(signatureForManipulatedMessage(onlyUppercased: false), expectedSignature)
    }
}
