<?php
namespace Base\Tool;

use \ZipArchive;
use CFPropertyList\CFPropertyList;

/**
 * 用于读取plist文件信息
 * @author elf<360197197@qq.com>
 */
class PlistParser
{
    const IS_SELF_PARSER = false;
    const PREG_INFO_PLIST = "/^Payload.*?\.app\/Info.plist$/";

    private $xml;
    private $plist;

    public function openFromIpa($ipaFile, $preg)
    {
        $zip = new ZipArchive;
        if ($zip->open($ipaFile) === true) {
            $index = -1;
            for( $i = 0; $i < $zip->numFiles; $i++ ){
                $stat = $zip->statIndex($i);
                if (preg_match($preg, $stat['name'], $matches)) {
                    $index = $stat['index'];
                }
            }

            $content = $zip->getFromIndex($index);
            $zip->close();
            if ($content){
                if (self::IS_SELF_PARSER) {
                    $xml = new \DOMDocument();
                    $xml->loadXML($content);
                    $this->xml = $xml;
                } else {
                    $plist = new CFPropertyList();
                    $plist->parse($content);
                    $this->plist = $plist;
                }
                return true;
            }
        }
        return false;
    }

    public function open($xmlFile)
    {
        $xml = new \DOMDocument();
        $xml->load($xmlFile);
        $this->xml = $xml;
        return true;
    }

    public function getResult()
    {
        if (self::IS_SELF_PARSER) {
            $plistTag = $this->xml->getElementsByTagName('plist');
            $dict = $plistTag->item(0)->childNodes->item(1);
            return $this->parseDictNode($dict);
        } else {
            return $this->plist->toArray();
        }
    }

    public function parseDictNode($parentNode)
    {
        $lastKey = '';
        $dict = [];
        foreach ($parentNode->childNodes as $node) {
            if ($node instanceof \DOMElement) {
                if ($node->nodeName == 'key') {
                    $lastKey = $node->textContent;
                } else {
                    if ($node->nodeName == 'dict') {
                        $dict[$lastKey] = $this->parseDictNode($node);
                    } elseif ($node->nodeName == 'array') {
                        $dict[$lastKey] = $this->parseArrayNode($node);
                    } elseif($node->nodeName == 'true') {
                        $dict[$lastKey] = true;
                    } elseif($node->nodeName == 'false') {
                        $dict[$lastKey] = false;
                    } else {
                        $dict[$lastKey] = $node->textContent;
                    }
                }
            }
        }
        return $dict;
    }

    public function parseArrayNode($parentNode)
    {
        $list = [];
        foreach ($parentNode->childNodes as $node) {
            if ($node instanceof \DOMElement) {
                if ($node->nodeName == 'dict') {
                    $list[] = $this->parseDictNode($node);
                } elseif ($node->nodeName == 'array') {
                    $list[] = $this->parseArrayNode($node);
                } elseif($node->nodeName == 'true') {
                    $list[] = true;
                } elseif($node->nodeName == 'false') {
                    $list[] = false;
                } else {
                    $list[] = $node->textContent;
                }
            }
        }
        return $list;
    }
}