#!/usr/bin/env raku

use Node::Ethereum::KeyStore::V3;

sub MAIN (
    Str  :$keystorepath!,
    Str  :$password!,
    Str  :$privatekey,
    Bool :$tron = False
)
{
    X::AdHoc.new(:payload('blank password is given')).throw unless $password && $password.chars;

    if $privatekey && $privatekey ~~ m:i/^ <xdigit>**64 $/ {
        X::AdHoc.new(:payload(sprintf("keystore %s exists, overwrite is not allowed for secure reasons", $keystorepath))).throw if $keystorepath && $keystorepath.IO.f;

        my $ksobj    = Node::Ethereum::KeyStore::V3.new(:$keystorepath);
        my $keystore = $ksobj.keystore(:$password, :secret($privatekey), :tron($tron));

        X::AdHoc.new(:payload('keystore generation failure')).throw unless $keystore ~~ Hash && $keystore<crypto> ~~ Hash;

        $ksobj.save(:$keystore);

        X::AdHoc.new(:payload(sprintf("can not save keystore %s", $keystorepath))).throw unless $keystorepath.IO.f;

        sprintf("keystore %s is successfully saved", $keystorepath).say;

        return 0;
    }
    else {
        X::AdHoc.new(:payload(sprintf("keystore %s not found", $keystorepath))).throw unless $keystorepath && $keystorepath.IO.f;

        my $decrypted = Node::Ethereum::KeyStore::V3.new(:$keystorepath).decrypt_key(:$password);

        X::AdHoc.new(:payload('decryption failure')).throw unless
            $decrypted ~~ Hash && ($decrypted<str>:exists) && $decrypted<str>.chars;

        $decrypted<str>.say;
    }
}
