//
//  XSPhoneInfo.m
//  nochange
//
//  Created by mac on 2024/10/15.
//

#import <Foundation/Foundation.h>
#import <IOKit/IOKitLib.h>
#import <IOKit/ps/IOPowerSources.h>
#import <IOKit/ps/IOPSKeys.h>
#import <UIKit/UIKit.h>
#import <mach/mach.h>
#import <mach/mach_host.h>
#import <sys/sysctl.h>
#import <malloc/malloc.h>
#import "XSPhoneInfo.h"


@interface XSPhoneInfo()
{

}
@property (nonatomic, strong) NSTimer *monitorTimer;
@property (nonatomic, assign) BOOL isMonitoring;


@property (nonatomic, copy) void (^memoryWarningHandler)(double availableMemory);
@end


@implementation XSPhoneInfo {
    dispatch_source_t _memoryPressureSource;
    natural_t mem_free;
    natural_t mem_total;
}

+(instancetype)sharedInstance
{
    static XSPhoneInfo* _sharedInstance = nil;
    
    static dispatch_once_t oncePredicate;
    dispatch_once (&oncePredicate, ^{
        _sharedInstance = [[XSPhoneInfo alloc] init];
    });
    return _sharedInstance;
}
-(instancetype)init {
    if (self = [super init]) {
        [self setupBatteryMonitoring];
        _pageSize = vm_page_size;
        [self startMemoryMonitoring];
        [self updateMemoryInfo];
        self.remoteIp = @"";
        return self;
    }
    return nil;
}

- (void)setupBatteryMonitoring {
    // 允许电池监控
    [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
    
    // 注册电池通知
    [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(batteryLevelDidChange:)
                                               name:UIDeviceBatteryLevelDidChangeNotification
                                             object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(batteryStateDidChange:)
                                               name:UIDeviceBatteryStateDidChangeNotification
                                             object:nil];
}
- (void)startBatteryMonitoring {
    if (!self.isMonitoring) {
        self.isMonitoring = YES;
        
        // 创建定时器定期更新电池信息
        self.monitorTimer = [NSTimer scheduledTimerWithTimeInterval:60.0
                                                           target:self
                                                         selector:@selector(updateBatteryInfo)
                                                         userInfo:nil
                                                          repeats:YES];
        [self updateBatteryInfo];
    }
}
- (void)updateBatteryInfo {
    // 更新基本电池信息
    _batteryLevel = [[UIDevice currentDevice] batteryLevel];
    _isCharging = [[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateCharging;
    _isFullyCharged = [[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateFull;
    
    // 获取详细电池信息
    [self updateDetailedBatteryInfo];
    //[self updateMemoryInfo];
}

- (void)updateDetailedBatteryInfo {
    @try {
        // 使用IOKit获取电池详细信息
        CFMutableDictionaryRef matching = IOServiceMatching("IOPMPowerSource");
        io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, matching);
        
        if (service) {
            CFMutableDictionaryRef properties = NULL;
            kern_return_t kr = IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, 0);
            
            if (kr == KERN_SUCCESS) {
                NSDictionary *batteryProps = (__bridge_transfer NSDictionary *)properties;
                
                // 更新基本信息
                  _batteryLevel = [[batteryProps objectForKey:@"CurrentCapacity"] floatValue] / 100.0;
                  _isCharging = [[batteryProps objectForKey:@"IsCharging"] boolValue];
                  _isFullyCharged = [[batteryProps objectForKey:@"FullyCharged"] boolValue];
                
                // 获取电池容量信息
                   _designCapacity = [[batteryProps objectForKey:@"DesignCapacity"] floatValue];
                   _maxCapacity = [[batteryProps objectForKey:@"AppleRawMaxCapacity"] floatValue];
                   _currentCapacity = [[batteryProps objectForKey:@"CurrentCapacity"] floatValue];
                   
                   // 获取电压信息
                   _batteryVoltage = [[batteryProps objectForKey:@"Voltage"] floatValue];
                   
                   // 获取循环次数
                   _cycleCount = [[batteryProps objectForKey:@"CycleCount"] integerValue];
                   
                   // 计算健康度
                   if (_designCapacity > 0 && _maxCapacity > 0) {
                       _batteryHealth = (_maxCapacity / _designCapacity) * 100;
                   }
             
                
                // 更新电池状态描述
                [self updateBatteryStatus:batteryProps];
            }
            
            IOObjectRelease(service);
        }
    } @catch (NSException *exception) {
        NSLog(@"Battery info update error: %@", exception);
    }
}
- (void)updateBatteryStatus:(NSDictionary *)batteryProps {
    NSMutableString *status = [NSMutableString string];
        
        // 基本状态
        if (_isCharging) {
            [status appendString:@"正在充电"];
        } else {
            [status appendString:@"使用电池中"];
        }
        
        // 健康状态
        if (_batteryHealth > 0) {
            //[status appendFormat:@"\n健康度: %ld%%", (long)_batteryHealth];
            /*
            if (_batteryHealth < 80) {
                [status appendString:@" (建议更换电池)"];
            } else if (_batteryHealth < 90) {
                [status appendString:@" (性能可能降低)"];
            }
             */
        }
        
        // 循环次数
        if (_cycleCount > 0) {
            //[status appendFormat:@"\n充电次数: %ld", (long)_cycleCount];
            /*
            if (_cycleCount > 500) {
                [status appendString:@" (使用时间较长)"];
            }
             */
        }
    self.batteryStatus = [status copy];
}

- (NSDictionary *)getBatteryInfo {
    return @{
        @"level": @(self.batteryLevel),
        @"isCharging": @(self.isCharging),
        @"isFullyCharged": @(self.isFullyCharged),
        @"health": @(self.batteryHealth),
        @"cycleCount": @(self.cycleCount),
        @"temperature": @(self.temperature),
        @"voltage": @(self.voltage),
        @"status": self.batteryStatus ?: @"未知"
    };
}

- (void)stopBatteryMonitoring {
    if (self.isMonitoring) {
        self.isMonitoring = NO;
        [self.monitorTimer invalidate];
        self.monitorTimer = nil;
    }
}
- (void)batteryLevelDidChange:(NSNotification *)notification {
    [self updateBatteryInfo];
}

- (void)batteryStateDidChange:(NSNotification *)notification {
    [self updateBatteryInfo];
}

#pragma mark - Memory Info Methods

- (void)updateMemoryInfo {
    mach_port_t host_port = mach_host_self();
    mach_msg_type_number_t host_size = HOST_VM_INFO_COUNT;
    vm_statistics_data_t vm_stat;
    
    if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
        NSLog(@"Failed to fetch vm statistics");
        return;
    }

    // 计算内存信息
    natural_t mem_used = (vm_stat.active_count +
                         vm_stat.inactive_count +
                         vm_stat.wire_count) * _pageSize;
    
    self->mem_free = vm_stat.free_count * _pageSize;
    self->mem_total = mem_used + mem_free;
    
    // 更新属性
    _totalMemory = self->mem_total / (1024.0 * 1024.0 * 1024.0);     // Convert to GB
    _availableMemory = self->mem_free / (1024.0 * 1024.0 * 1024.0);  // Convert to GB
    _usedMemory = mem_used / (1024.0 * 1024.0 * 1024.0);       // Convert to GB
    _memoryUsage = (mem_used * 100.0) / self->mem_total;             // Calculate percentage
}


- (double)getMemoryUsageForPid:(pid_t)pid {
    task_vm_info_data_t vmInfo;
    mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
    kern_return_t kernReturn = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&vmInfo, &count);
    
    if (kernReturn == KERN_SUCCESS) {
        return (double)vmInfo.phys_footprint / 1024.0 / 1024.0; // Convert to MB
    }
    
    return 0;
}

#pragma mark - Memory Monitoring


- (void)handleCriticalMemoryPressure {

    
    // 发送通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"MemoryCriticalNotification"
                                                      object:nil
                                                    userInfo:@{@"availableMemory": @(self.availableMemory)}];
}

- (void)handleWarningMemoryPressure {
    // 发送警告通知
    [[NSNotificationCenter defaultCenter] postNotificationName:@"MemoryWarningNotification"
                                                      object:nil
                                                    userInfo:@{@"availableMemory": @(self.availableMemory)}];
}

- (void)startMemoryMonitoring {
    // 创建定时器定期检查内存
    self.monitorTimer = [NSTimer scheduledTimerWithTimeInterval:30.0
                                                        target:self
                                                      selector:@selector(checkMemoryStatus)
                                                      userInfo:nil
                                                       repeats:YES];
}

- (void)stopMemoryMonitoring {
    [self.monitorTimer invalidate];
    self.monitorTimer = nil;
}

- (void)checkMemoryStatus {
    [self updateMemoryInfo];
    
   
}



- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [[UIDevice currentDevice] setBatteryMonitoringEnabled:NO];
    [self stopBatteryMonitoring];
    [self stopMemoryMonitoring];
    if (_memoryPressureSource) {
        dispatch_source_cancel(_memoryPressureSource);
    }
}

- (NSString *)IPAddress {
    
    NSDictionary *addresses = [self getIPAddresses];
    __block NSString *address;
    [addresses enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        address = obj;
        if(address) *stop = YES;
    }];
    return address ? address : @"0.0.0.0";
}



- (NSDictionary *)getIPAddresses {
    NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
    
    // retrieve the current interfaces - returns 0 on success
    struct ifaddrs *interfaces;
    if(!getifaddrs(&interfaces)) {
        // Loop through linked list of interfaces
        struct ifaddrs *interface;
        for(interface=interfaces; interface; interface=interface->ifa_next) {
            if(!(interface->ifa_flags & IFF_UP) || (interface->ifa_flags & IFF_LOOPBACK)) {
                continue; // deeply nested code harder to read
            }
            const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
            char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
            if(addr && (addr->sin_family==AF_INET)) {
                NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
                NSString *type;
                if(addr->sin_family == AF_INET) {
                    if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
                        type = @"ipv4";
                    }
                }
                if(type) {
                    NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
                    addresses[key] = [NSString stringWithUTF8String:addrBuf];
                }
            }
        }
        // Free memory
        freeifaddrs(interfaces);
    }
    return [addresses count] ? addresses : nil;
}

- (NSString *)CurrentThermalState {
    NSProcessInfoThermalState state = [NSProcessInfo processInfo].thermalState;
    
    switch (state) {
        case NSProcessInfoThermalStateNominal:
            return @"Nominal";
        case NSProcessInfoThermalStateFair:
            return @"Fair";
        case NSProcessInfoThermalStateSerious:
            return @"Serious";
        case NSProcessInfoThermalStateCritical:
            return @"Critical";
        default:
            return @"Unknown";
    }
}

- (NSString *)DiskSize {
    @try {
        // 磁盘
        NSDictionary<NSFileAttributeKey, id> *info = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
        NSLog(@"diskinfo: %@", info);
        int64_t size = [info[NSFileSystemSize] longLongValue]; // 总大小
        int64_t space =  [[info objectForKey:NSFileSystemFreeSize] longLongValue];
        
        NSString *gb = [NSByteCountFormatter stringFromByteCount:size countStyle:NSByteCountFormatterCountStyleDecimal];
        NSString *space_gb = [NSByteCountFormatter stringFromByteCount:space countStyle:NSByteCountFormatterCountStyleDecimal];
        return [NSString stringWithFormat:@"%@/%@",  space_gb,gb];
    } @catch (NSException *exception) {
        return @"";
    }
}

- (NSString *)IPhoneStatus {
    [self updateBatteryInfo];
    [self updateMemoryInfo];
    NSString *gb = [NSByteCountFormatter stringFromByteCount: self->mem_total countStyle:NSByteCountFormatterCountStyleDecimal];
    NSString *space_gb = [NSByteCountFormatter stringFromByteCount:self->mem_free countStyle:NSByteCountFormatterCountStyleDecimal];
    NSString *mem = [NSString stringWithFormat:@"%@/%@",  space_gb,gb];
    
    NSString *res = [NSString stringWithFormat:@"电池%ld%%,%@;内存%@;磁盘%@",(long)(self.batteryLevel*100), self.batteryStatus,
                     mem,self.DiskSize
    ];
    return res;
}


@end

