package znx.impl;

import org.jkiss.lm.*;
import znx.utils.Base64;
import znx.utils.DateUtils;
import znx.utils.LMEncryption;
import znx.utils.RSAUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;
import java.util.logging.Logger;

public class LMMain
{
    private static final Logger log;
    public static final LMProduct PRODUCT;

    static {
        log = Logger.getLogger("LMMain");
        PRODUCT = new LMProduct("dbeaver-ee", "DB", "DBeaver Enterprise", "DBeaver Enterprise Edition", "6.0.0.201903111000", new Date());
    }

    public static void main(final String[] args) throws Exception {
        System.out.println("LM 1.0");
        if (args.length > 0 && args[0].equals("gen-keys")) {
            System.out.println("Test key generation");
            generateKeyPair();
        }
//        else if (args.length > 0 && args[0].equals("encrypt-license")) {
//            System.out.println("Encrypt license");
//            encryptLicense();
//        }
        else if (args.length > 0 && args[0].equals("decrypt-license")) {
            System.out.println("Decrypt license");
            decryptLicense();
        }
//        else if (args.length > 0 && args[0].equals("import-license")) {
//            System.out.println("Import license");
//            importLicense();
//        }
        else {
            System.out.println("Test license generation");
            generateLicense();
        }
    }

//    private static void encryptLicense() throws Exception {
//        final PrivateKey privateKey = readPrivateKey();
//        final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
//        final String licenseID = LMUtils.generateLicenseId(LMMain.PRODUCT);
//        System.out.println("License ID: " + licenseID);
//        System.out.println("Product ID (" + LMMain.PRODUCT.getId() + "):");
//        String productID = in.readLine();
//        if (productID.isEmpty()) {
//            productID = LMMain.PRODUCT.getId();
//        }
//        System.out.println("Product version (" + LMMain.PRODUCT.getVersion() + "):");
//        String productVersion = in.readLine();
//        if (productVersion.isEmpty()) {
//            productVersion = LMMain.PRODUCT.getVersion();
//        }
//        System.out.println("Owner ID (1):");
//        String ownerID = in.readLine();
//        if (ownerID.isEmpty()) {
//            ownerID = "1";
//        }
//        System.out.println("Owner company (JKISS):");
//        String ownerCompany = in.readLine();
//        if (ownerCompany.isEmpty()) {
//            ownerCompany = "JKISS";
//        }
//        System.out.println("Owner name:");
//        final String ownerName = in.readLine();
//        System.out.println("Owner email:");
//        final String ownerEmail = in.readLine();
//        final LMLicense license = new LMLicense(licenseID, LMLicenseType.YEAR_UPDATE, new Date(), new Date(), null, 0L, productID, productVersion, ownerID, ownerCompany, ownerName, ownerEmail);
//        final byte[] licenseData = license.getData();
//        final byte[] licenseEncrypted = LMEncryption.encrypt(licenseData, privateKey);
//        System.out.println("--- LICENSE ---");
//        System.out.println(Base64.splitLines(Base64.encode(licenseEncrypted), 76));
//    }

    private static void decryptLicense() throws Exception {
        final PublicKey publicKey = readPublicKey();
        System.out.println("License:");
        final byte[] encryptedLicense = LMUtils.readEncryptedString(System.in);
        final LMLicense license = new LMLicense(encryptedLicense, publicKey);
        System.out.println(license);
    }

//    private static void importLicense() throws Exception {
//        final PrivateKey privateKey = readPrivateKey();
//        final PublicKey publicKey = readPublicKey();
//        System.out.println("License:");
//        final byte[] encryptedLicense = LMUtils.readEncryptedString(System.in);
//        final LMLicenseManager lm = new LMLicenseManager(new LMKeyProvider() {
//            @Override
//            public Key getEncryptionKey(final LMProduct product) {
//                return privateKey;
//            }
//
//            @Override
//            public Key getDecryptionKey(final LMProduct product) {
//                return publicKey;
//            }
//        }, null);
//        lm.importLicense(LMMain.PRODUCT, encryptedLicense, false);
//    }

    private static PublicKey readPublicKey() throws LMException {
        final File keyFile = new File(new File(System.getProperty("user.home"), ".jkiss-lm"), "public-key.txt");
        if (!keyFile.exists()) {
            throw new LMException("Cannot find public key file (" + keyFile.getAbsolutePath() + ")");
        }
        try {
            Throwable t = null;
            try {
                final InputStream keyStream = new FileInputStream(keyFile);
                try {
                    final byte[] keyData = LMUtils.readEncryptedString(keyStream);
                    return LMEncryption.generatePublicKey(keyData);
                }
                finally {
                    if (keyStream != null) {
                        keyStream.close();
                    }
                }
            }
            finally {
//                if (t == null) {
//                    final Throwable t2;
//                    t = t2;
//                }
//                else {
//                    final Throwable t2;
//                    if (t != t2) {
//                        t.addSuppressed(t2);
//                    }
//                }
            }
        }
        catch (Exception e) {
            throw new LMException(e);
        }
    }

    private static void generateKeyPair() throws LMException {
        final KeyPair keyPair = LMEncryption.generateKeyPair(2048);
        final PublicKey publicKey = keyPair.getPublic();
        final PrivateKey privateKey = keyPair.getPrivate();
        System.out.println("--- PUBLIC KEY ---");
        System.out.println(Base64.splitLines(Base64.encode(publicKey.getEncoded()), 76));
        System.out.println("--- PRIVATE KEY ---");
        System.out.println(Base64.splitLines(Base64.encode(privateKey.getEncoded()), 76));
    }

    public static void generateLicense()  {
        try{
            String licenseId = LMUtils.generateLicenseId(LMMain.PRODUCT);
            LMLicenseType licenseType = LMLicenseType.ULTIMATE;
            Date licenseIssueTime = new Date();
            Date licenseStartTime = new Date();
            Date licenseEndTime = DateUtils.convertStringToDate("9999-12-31 23:59:59","yyyy-MM-dd HH:mm:ss");
            long flags = 0L;
            String productId = LMMain.PRODUCT.getId();
            String productVersion = LMMain.PRODUCT.getVersion();
            String ownerId = "ZNX";
            String ownerCompany = "ZNX";
            String ownerName = "ZNX";
            String ownerEmail = "znx.52pojie.com";

            PublicKey publicKey = null;
            PrivateKey privateKey = null;
//        KeyPair keyPair = LMEncryption.generateKeyPair(2048);
//        publicKey = keyPair.getPublic();
//        privateKey = keyPair.getPrivate();
//        System.out.println("公钥："+Base64.encode(publicKey.getEncoded()));
//        System.out.println("私钥："+Base64.encode(privateKey.getEncoded()));
            String publicKeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+P6vi0hjnkZ2YarINFC3dSPWgDMQxJYRl49A2d3K+FXv4OICoCEIgmAeqZrWh+N0hqpoGubGSas1fCkhQfi55RU4vz9LkJtBjHmXhW2rJr50x3rTLeK72NL9Qz6ADnUyGQX9UnFsbDz3YK0KrLSmTDtcOZIAGZa2lTyDv4oATSjH+73ILIWlH9DevblsWXOHui7PcxkXCcP9UVdr0hKHaMM1aMMKYp6g8aUDED6cDkXqHxfL8mmqAIKVVpmexE+8jB1jRQBZKGcPVK6aNfmcaCgRGnwWXKabBoOOXRH0kNhb7wcyNGNqhaT+ZOiPfXosCJpHmHvqHd19HCJW8AAYwIDAQAB";
            String privateKeyStr = "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCz4/q+LSGOeRnZhqsg0ULd1I9aAMxDElhGXj0DZ3cr4Ve/g4gKgIQiCYB6pmtaH43SGqmga5sZJqzV8KSFB+LnlFTi/P0uQm0GMeZeFbasmvnTHetMt4rvY0v1DPoAOdTIZBf1ScWxsPPdgrQqstKZMO1w5kgAZlraVPIO/igBNKMf7vcgshaUf0N69uWxZc4e6Ls9zGRcJw/1RV2vSEodowzVowwpinqDxpQMQPpwOReofF8vyaaoAgpVWmZ7ET7yMHWNFAFkoZw9Urpo1+ZxoKBEafBZcppsGg45dEfSQ2FvvBzI0Y2qFpP5k6I99eiwImkeYe+od3X0cIlbwABjAgMBAAECggEBAIhMnJerqllA+I0QtGjRJVDe1R7kq9/F7oyiqqgBpRHiU5IQHuuWJIeFm4tSvNQ0REiFWzDpV0LfQuV2x7DkINBGW2sBNPPv8JtZA6sV2Ks/YTrM2JPwHZz0J4Esq9+v8cFD1cNMejYAVUXo2onfpCHeKIn6cWOcKgpzglRJzhXaeoy6IeGo5gtNCs46QUv0qG2BfzyV5DkqhTSHtooCQbHhXK3njaDjBHSuVVWbO6FAiekJZP0pB3JXNPyJbBY0y6AnU996ViybXHqgQDr1cpup2m7K+4Gcrz/AmrmeiDpJCUSLwjLPXx8+C0EsPz4+s2zwIu2Ur2BglQZ5ERZ4LAECgYEA/MuyngmPcm+NzEZeisn40OIHok3qCEsPvclclJLGRhBsnKVRplGvrAWcfZts4Uz4NapJyCCz3waRSmN9DBBIYYfMv1ZvjSASJrkHLngDc7TgO1pdvfzml2FKamaF1D7ZhoRVm+ttfAGR74AYk9ybcIko7IBvdSUW7sQemoweWUECgYEAtiu10WuMBUBv2KXIfS/RrxHaJN3LAvGg6yZGWhMEiIFW3P5Zlk1lZjrsNi2ZJ4zGVM61ggg1JH6Dj3bNLrNefOEykde1YE+wM3RkUcU/SDWSn5nM9UwMZjXpXP84hAcjEANBLysWBpyyHxikliRSv4bD8/z5jAQEPOnis2GWLKMCgYEA6Z/7MBDX0EOGQW4bO5rS54Cs23O0QPvVzWjFtc07jk7pgY9LOTEu8ASzjmXQpxsyHK6Gx3xpn0j7h0sQqtB1hCUztPTV3Q/xlnXTTD+/uPRFcrTeA5IxLV/NnS2oqvF2qNmuII3gPgVZcITqsePkh4lLF97Oou2nFvyK5/tspMECgYBrIYd6UeH1ULC12sDuBgotB7WfCqQR5iF5SHgFDrwSvuVjb10mC/v+w9YYAnbYEGyugSWzA7qk7JXX78i4lxmRHSqNJCrxKcv4ZpF8mSAfCgphO6SR+Rgtn7TOUPVeh4fyKcfSwmbgmpQRv39DILddFRb1zKbA1bfcTrtYPKKBOwKBgQCODOTr+vzWpm6YA83QjckyWCIH2qqBz/A1JBkXnBKBo4T7Z4YzfYgcGx4KrAHM9CmoZwmBFb6SHtfVX3IMwPRDjpGCqBDqEdbSGWHAEl8MFIMccJM6fu5M1ahhOHoHHel1+bP3hExbVgDiZ4VY1DYEf+SkXDR645mamVQzAEiURQ==";
//            System.out.println("publicKey:"+publicKeyStr);
//            System.out.println("privateKey:"+privateKeyStr);
            publicKey = RSAUtils.getPublicKey(publicKeyStr);
            privateKey = RSAUtils.getPrivateKey(privateKeyStr);
            final LMLicense license = new LMLicense(licenseId, licenseType,licenseIssueTime, licenseStartTime, licenseEndTime, flags, productId, productVersion, ownerId, ownerCompany, ownerName, ownerEmail);
            final byte[] data = license.getData();
            final byte[] encrypted = LMEncryption.encrypt(data, privateKey);
//            System.out.println(new StringBuffer().append("********************************\nlicense text:\n-----------------------------\n\n").append("--- PUBLIC KEY ---\n").append(new String(Base64.encode(encrypted))).append("\n\n********************************\n"));
            System.out.println(new StringBuffer().append("********************************\n").append("--- PUBLIC KEY ---\n").append(new String(Base64.encode(encrypted))).append("\n\n********************************\n"));
            final String encodedBase64 = Base64.splitLines(Base64.encode(encrypted), 76);
            final byte[] encodedBinary = Base64.decode(encodedBase64);
            final LMLicense licenseCopy = new LMLicense(encodedBinary, publicKey);
//            System.out.println(licenseCopy);
            final LMSubscription subscription = new LMSubscription(licenseId, LMSubscriptionPeriod.MONTH, new Date(), new Date(), 1, true);
            final byte[] subData = LMEncryption.encrypt(subscription.getData(), privateKey);
            final String subBase64 = Base64.splitLines(Base64.encode(subData), 76);
            final byte[] subBinary = Base64.decode(subBase64);
            final LMSubscription subCopy = new LMSubscription(subBinary, publicKey);
//            System.out.println(subCopy);
        }catch (Exception e){

        }
    }
}
