package tracker;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.persistence.*;
import com.dampcake.bencode.Bencode;
import com.dampcake.bencode.Type;
import com.querydsl.jpa.impl.JPAUpdateClause;
import entity.*;
import entity.config;
import java.util.Scanner;
import java.io.IOException;
public class Tracker implements TrackerInterface {
    private final EntityManagerFactory emf;
    // 默认构造：产线数据库
    public Tracker() {
        config cfg = new config();
        Map<String,Object> props = new HashMap<>();
        props.put("javax.persistence.jdbc.url",
                  "jdbc:mysql://" + cfg.SqlURL + "/" + cfg.Database);
        props.put("javax.persistence.jdbc.user", cfg.SqlUsername);
        props.put("javax.persistence.jdbc.password", cfg.SqlPassword);
        this.emf = Persistence.createEntityManagerFactory("myPersistenceUnit", props);
    }
    // 测试传入：测试库
    public Tracker(EntityManagerFactory emf) {
        this.emf = emf;
    }
    @Override
    public boolean AddUpLoad(String userid, int upload, String infoHash) {
        long newTotal = upload;  // convert to long
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        try {
            // 1) find the seedId by infoHash
            String seedId = em.createQuery(
                "SELECT s.seedId FROM SeedHash s WHERE s.infoHash = :ih", String.class)
                .setParameter("ih", infoHash)
                .getSingleResult();
            // 2) sum existing uploads for this user+seed
            Long sumSoFar = em.createQuery(
                "SELECT COALESCE(SUM(t.upload),0) FROM TransRecord t WHERE t.uploaduserid = :uid AND t.seedid = :sid",
                Long.class)
                .setParameter("uid", userid)
                .setParameter("sid", seedId)
                .getSingleResult();
            long delta = newTotal - sumSoFar;
            if (delta < 0L) {
                tx.rollback();
                return false;   // error: newTotal less than already recorded
            }
            if (delta == 0L) {
                tx.rollback();
                return false;  // nothing to do
            }
            // 3) persist a new TransRecord with only the delta
            TransRecord rd = new TransRecord();
            rd.taskid       = UUID.randomUUID().toString();
            rd.uploaduserid = userid;
            rd.seedid       = seedId;
            rd.upload       = delta;
            rd.maxupload    = newTotal;
            em.persist(rd);
            em.flush();
            // 4) 重新计算用户的总上传，确保与 TransRecord 完全一致
            Long totalUpload = em.createQuery(
                "SELECT COALESCE(SUM(t.upload),0) FROM TransRecord t WHERE t.uploaduserid = :uid",
                Long.class
            )
            .setParameter("uid", userid)
            .getSingleResult();

            Long PTuploadbefor = em.createQuery(
                "SELECT t.upload FROM UserPT t WHERE t.userid = :uid",
                Long.class
            ).setParameter("uid", userid)
            .getSingleResult();
            
        
            UserPT user = em.find(UserPT.class, userid);
            user.upload = totalUpload;
            em.merge(user);
            em.flush();
            tx.commit();

            Long PTuploadafter = em.createQuery(
                "SELECT t.upload FROM UserPT t WHERE t.userid = :uid",
                Long.class
            ).setParameter("uid", userid)
            .getSingleResult();

            System.out.println("按回车继续...");
            System.out.printf("thisadd:%d userptsofar:%d userptafter:%d totaluploadnow:%d delta:%d%n",upload, PTuploadbefor,PTuploadafter, totalUpload,delta);
            System.out.println("按回车继续...");
            return false;      // success
        } catch (RuntimeException ex) {
            if (tx.isActive()) tx.rollback();
            throw ex;
        } finally {
            em.close();
        }
    }
    
    @Override
    public boolean ReduceUpLoad(String userid, int upload){
        long uploadLong = upload;  // convert to long
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        try {
            // 1) fetch user and ensure enough upload to reduce
            UserPT user = em.find(UserPT.class, userid);
            long before = user.upload;
            if (uploadLong > before) {
                tx.rollback();
                return true;   // error: cannot reduce more than current total
            }
            // 2) subtract
            user.upload = before - uploadLong;
            em.merge(user);
            // (optional) record a negative TransRecord so sums stay in sync
            TransRecord rd = new TransRecord();
            rd.taskid       = UUID.randomUUID().toString();
            rd.uploaduserid = userid;
            rd.seedid       = null;
            rd.upload       = -uploadLong;
            rd.maxupload    = user.upload;
            em.persist(rd);
            tx.commit();
            return false;      // success
        } catch (RuntimeException ex) {
            if (tx.isActive()) tx.rollback();
            throw ex;
        } finally {
            em.close();
        }
    }
    @Override
    public boolean AddDownload(String userid, int download, String infoHash) {
        long newTotal = download;  // convert to long
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            // 1. 查 SeedHash
            TypedQuery<SeedHash> qsh = em.createQuery(
                "SELECT s FROM SeedHash s WHERE s.infoHash = :h", SeedHash.class);
            qsh.setParameter("h", infoHash);
            List<SeedHash> shl = qsh.getResultList();
            if (shl.isEmpty()) {
                System.out.println("seed没有被记录");
                return false;
            }
            String seedid = shl.get(0).seedId;

            // 2. 统计该用户在该种子上的已有 download
            TypedQuery<Long> qsum = em.createQuery(
                "SELECT COALESCE(SUM(t.download),0) FROM TransRecord t " +
                "WHERE t.seedid = :sid AND t.downloaduserid = :uid", Long.class);
            qsum.setParameter("sid", seedid);
            qsum.setParameter("uid", userid);
            long oldSeedSum = qsum.getSingleResult();

            long diff = newTotal - oldSeedSum;
            if (diff <= 0) return false;
            
            System.out.println("AddDownload: 该种子原有总量=" + oldSeedSum + ", 新总量=" + newTotal + ", 增量=" + diff);

            try {
                tx.begin();
                // 1. persist 增量记录
                TransRecord tr = new TransRecord();
                tr.taskid         = UUID.randomUUID().toString();
                tr.downloaduserid = userid;
                tr.seedid         = seedid;
                tr.download       = diff;
                tr.maxdownload    = newTotal;
                em.persist(tr);

                // 2. 全表重新累计该用户所有种子的 download，并更新 UserPT.download
                TypedQuery<Long> qTotal = em.createQuery(
                    "SELECT COALESCE(SUM(t.download),0) FROM TransRecord t WHERE t.downloaduserid = :uid",
                    Long.class
                )
                .setParameter("uid", userid);
                long userTotalDownload = qTotal.getSingleResult();
                QUserPT quser = QUserPT.userPT;
                new JPAUpdateClause(em, quser)
                    .where(quser.userid.eq(userid))
                    .set(quser.download, userTotalDownload)
                    .execute();

                tx.commit();
                return false;
            } catch (Exception e) {
                if (tx.isActive()) tx.rollback();
                return true;
            } finally {
                em.close();
            }
        } catch (Exception e) {
            return true;
        }
    }
    @Override
    public boolean ReduceDownload(String userid, int download) {
        long downloadLong = download;  // convert to long
        EntityManager em = emf.createEntityManager();
        try {
            // 1. 预检查当前值
            TypedQuery<Long> qcurr = em.createQuery(
                "SELECT u.download FROM UserPT u WHERE u.userid = :uid", Long.class);
            qcurr.setParameter("uid", userid);
            long current = qcurr.getSingleResult();
            if (downloadLong > current) {
                em.close();
                return false;
            }
            // 2. 执行减法更新
            EntityTransaction tx = em.getTransaction();
            tx.begin();
            QUserPT q = QUserPT.userPT;
            new JPAUpdateClause(em, q)
                .where(q.userid.eq(userid))
                .set(q.download, q.download.subtract(downloadLong))
                .execute();
            tx.commit();
            return false;
        } catch(Exception e) {
            return true;
        } finally {
            if (em.isOpen()) em.close();
        }
    }
    @Override
    public boolean AddMagic(String userid, int magic) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            QUserPT q = QUserPT.userPT;
            long updated = new JPAUpdateClause(em, q)
                .where(q.userid.eq(userid))
                .set(q.magic, q.magic.add(magic))
                .execute();
            tx.commit();
            return updated <= 0;
        } catch(Exception e) {
            if (tx.isActive()) tx.rollback();
            return true;
        } finally {
            em.close();
        }
    }
    @Override
    public boolean ReduceMagic(String userid, int magic) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            QUserPT q = QUserPT.userPT;
            long updated = new JPAUpdateClause(em, q)
                .where(q.userid.eq(userid))
                .set(q.magic, q.magic.subtract(magic))
                .execute();
            tx.commit();
            return updated <= 0;
        } catch(Exception e) {
            if (tx.isActive()) tx.rollback();
            return true;
        } finally {
            em.close();
        }
    }
    @Override
    public int SaveTorrent(String seedid, File TTorent){
        try {
            Path storageDir = Paths.get(config.TORRENT_STORAGE_DIR);
            if (!Files.exists(storageDir)) {
                Files.createDirectories(storageDir);
            }
            String filename = TTorent.getName();
            Path target = storageDir.resolve(seedid + "_" + filename);
            Files.copy(TTorent.toPath(), target, StandardCopyOption.REPLACE_EXISTING);

            // Calculate infoHash using ISO_8859_1 encoding method to match qBittorrent
            String infoHash = null;
            try {
                infoHash = calculateInfoHashReencoding(target.toFile());
                System.out.println("InfoHash (ISO_8859_1): " + infoHash);
            } catch (Exception e) {
                System.err.println("Warning: could not parse torrent infoHash: " + e.getMessage());
                // Fallback to direct extraction method
                try {
                    infoHash = calculateInfoHashDirect(target.toFile());
                    System.out.println("InfoHash (Direct): " + infoHash);
                } catch (Exception e2) {
                    System.err.println("Warning: fallback infoHash calculation also failed: " + e2.getMessage());
                }
            }

            EntityManager em = emf.createEntityManager();
            EntityTransaction tx = em.getTransaction();
            try {
                tx.begin();
                Seed seed = em.find(Seed.class, seedid);
                seed.url = target.toString();
                em.merge(seed);

                // upsert SeedHash only if we have a valid infoHash
                if (infoHash != null) {
                    SeedHash sh = new SeedHash();
                    sh.seedId = seedid;
                    sh.infoHash = infoHash;
                    em.merge(sh);
                }
                tx.commit();
                return 0;
            } catch (Exception e) {
                if (tx.isActive()) tx.rollback();
                return 1;
            } finally {
                em.close();
            }
        } catch (Exception e) {
            return 1;
        }
    }
    @Override
    public File GetTTorent(String seedid, String userid) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        File file = null;
        try {
            Seed seed = em.find(Seed.class, seedid);
            if (seed == null || seed.url == null) {
                return null;
            }
            file = new File(seed.url);
            if (!file.exists()) {
                return null;
            }
            tx.begin();
            SeedDownload sd = new SeedDownload();
            sd.seedId = seedid;
            sd.userId = userid;
            LocalDateTime now = LocalDateTime.now();
            sd.downloadStart = now;
            sd.downloadEnd = now;
            em.persist(sd);
            tx.commit();
        } catch (Exception e) {
            if (tx.isActive()) tx.rollback();
            // ignore persistence errors and still return the file
        } finally {
            em.close();
        }
        return file;
    }
    @Override
    public int AddRecord(TransRecord rd){
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            em.persist(rd);
            tx.commit();
            // 返回1表示插入成功
            return 1;
        } catch (Exception e) {
            if (tx.isActive()) tx.rollback();
            return -1;
        } finally {
            em.close();
        }
    }
    
    /**
     * Calculate infoHash by extracting the original info dictionary bytes
     * from the torrent file, rather than re-encoding the parsed data.
     * This method preserves the original binary representation.
     */
    private String calculateInfoHashDirect(File torrentFile) throws Exception {
        byte[] torrentData = Files.readAllBytes(torrentFile.toPath());
        
        // Find the info dictionary in the raw torrent data
        int infoStart = findInfoDictionary(torrentData);
        if (infoStart == -1) {
            throw new Exception("Could not find info dictionary in torrent file");
        }
        
        // Extract the info dictionary bytes directly from the original torrent
        byte[] infoBytes = extractInfoBytes(torrentData, infoStart);
        
        // Debug: print first few bytes of info dict
        System.out.print("Info dict starts with: ");
        for (int i = 0; i < Math.min(20, infoBytes.length); i++) {
            System.out.printf("%02x ", infoBytes[i] & 0xff);
        }
        System.out.println();
        
        // Calculate SHA1 hash
        MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
        byte[] digest = sha1.digest(infoBytes);
        
        // Convert to hex string
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            sb.append(String.format("%02x", b & 0xff));
        }
        
        return sb.toString();
    }
    
    /**
     * Correct method using ISO_8859_1 encoding for infohash calculation
     * This matches qBittorrent's calculation method
     */
    private String calculateInfoHashReencoding(File torrentFile) throws Exception {
        byte[] torrentData = Files.readAllBytes(torrentFile.toPath());
        
        // Use ISO_8859_1 charset for infohash calculation (as per BitTorrent specification)
        Bencode bencodeInfoHash = new Bencode(java.nio.charset.StandardCharsets.ISO_8859_1);
        
        @SuppressWarnings("unchecked")
        Map<String,Object> meta = bencodeInfoHash.decode(torrentData, Type.DICTIONARY);
        @SuppressWarnings("unchecked")
        Map<String,Object> info = (Map<String,Object>) meta.get("info");
        
        if (info == null) {
            throw new Exception("No info dictionary found");
        }
        
        // Re-encode the info dictionary using ISO_8859_1
        byte[] infoBytes = bencodeInfoHash.encode(info);
        
        // Calculate SHA1 hash
        MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
        byte[] digest = sha1.digest(infoBytes);
        
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            sb.append(String.format("%02x", b & 0xff));
        }
        
        return sb.toString();
    }
    
    /**
     * Find the position of "4:info" in the torrent data
     */
    private int findInfoDictionary(byte[] data) {
        byte[] pattern = "4:info".getBytes();
        
        for (int i = 0; i <= data.length - pattern.length; i++) {
            boolean found = true;
            for (int j = 0; j < pattern.length; j++) {
                if (data[i + j] != pattern[j]) {
                    found = false;
                    break;
                }
            }
            if (found) {
                return i;
            }
        }
        return -1;
    }
    
    /**
     * Extract the info dictionary bytes from the original torrent data
     */
    private byte[] extractInfoBytes(byte[] data, int infoStart) throws Exception {
        // Skip "4:info" to get to the actual dictionary content
        int dictStart = infoStart + 6; // "4:info".length()
        
        if (dictStart >= data.length || data[dictStart] != 'd') {
            throw new Exception("Invalid info dictionary format");
        }
        
        // Find the matching 'e' that closes the info dictionary
        int dictEnd = findMatchingEnd(data, dictStart);
        if (dictEnd == -1) {
            throw new Exception("Could not find end of info dictionary");
        }
        
        // Extract the info dictionary bytes (including 'd' and 'e')
        int length = dictEnd - dictStart + 1;
        byte[] infoBytes = new byte[length];
        System.arraycopy(data, dictStart, infoBytes, 0, length);
        
        return infoBytes;
    }
    
    /**
     * Find the matching 'e' for a dictionary that starts with 'd'
     */
    private int findMatchingEnd(byte[] data, int start) {
        if (start >= data.length || data[start] != 'd') {
            return -1;
        }
        
        int depth = 0;
        int i = start;
        
        while (i < data.length) {
            byte b = data[i];
            
            if (b == 'd' || b == 'l') {
                // Dictionary or list start
                depth++;
                i++;
            } else if (b == 'e') {
                // Dictionary or list end
                depth--;
                if (depth == 0) {
                    return i;
                }
                i++;
            } else if (b == 'i') {
                // Integer: i<number>e
                i++; // skip 'i'
                while (i < data.length && data[i] != 'e') {
                    i++;
                }
                if (i < data.length) i++; // skip 'e'
            } else if (b >= '0' && b <= '9') {
                // String: <length>:<string>
                int lengthStart = i;
                while (i < data.length && data[i] >= '0' && data[i] <= '9') {
                    i++;
                }
                if (i < data.length && data[i] == ':') {
                    // Parse length
                    String lengthStr = new String(data, lengthStart, i - lengthStart);
                    int length = Integer.parseInt(lengthStr);
                    i++; // skip ':'
                    i += length; // skip string content
                } else {
                    // Invalid format
                    return -1;
                }
            } else {
                // Unknown character
                i++;
            }
        }
        
        return -1;
    }
}