<?php

/**
 * Takes an array of keys to strings, probably generated by
 * HTMLPurifier_ConfigSchema_StringHashParser
 */
class HTMLPurifier_ConfigSchema_StringHashAdapter
{
    
    /**
     * Takes a string hash and calls the appropriate functions in $schema
     * based on its values.
     */
    public function adapt($hash, $schema) {
        
        if (! $hash instanceof HTMLPurifier_ConfigSchema_StringHash) {
            $hash = new HTMLPurifier_ConfigSchema_StringHash($hash);
        }
        
        if (!isset($hash['ID'])) {
            trigger_error('Missing key ID in string hash');
            return;
        }
        
        // Check namespace:
        if (strpos($hash['ID'], '.') === false) {
            // This will cause problems if we decide to support nested
            // namespaces, but for now it's ok.
            $schema->addNamespace($hash->offsetGet('ID'), $hash->offsetGet('DESCRIPTION'));
            $this->_findUnused($hash);
            return;
        }
        
        list($ns, $directive) = explode('.', $hash->offsetGet('ID'), 2);
        
        if (isset($hash['TYPE'], $hash['DEFAULT'], $hash['DESCRIPTION'])) {
            $type         = $hash->offsetGet('TYPE');
            $raw_default  = $hash->offsetGet('DEFAULT');
            $default      = eval("return $raw_default;");
            $description  = $hash->offsetGet('DESCRIPTION');
            $schema->add($ns, $directive, $default, $type, $description);
        }
        
        if (isset($hash['ALLOWED'])) {
            $raw_allowed = $hash->offsetGet('ALLOWED');
            $allowed     = eval("return array($raw_allowed);");
            $schema->addAllowedValues($ns, $directive, $allowed);
        }
        
        // This must be after ALLOWED
        if (isset($hash['VALUE-ALIASES'])) {
            $raw_value_aliases = $hash->offsetGet('VALUE-ALIASES');
            $value_aliases     = eval("return array($raw_value_aliases);");
            $schema->addValueAliases($ns, $directive, $value_aliases);
        }
        
        if (isset($hash['ALIASES'])) {
            $raw_aliases = trim($hash->offsetGet('ALIASES'));
            $aliases = preg_split('/\s*,\s*/', $raw_aliases);
            foreach ($aliases as $alias) {
                list($alias_ns, $alias_directive) = explode('.', $alias, 2);
                $schema->addAlias($alias_ns, $alias_directive, $ns, $directive);
            }
        }
        
        // We don't use these yet, but they're specified
        if (isset($hash['VERSION'])) $hash->offsetGet('VERSION');
        if (isset($hash['DEPRECATED-USE'])) $hash->offsetGet('DEPRECATED-USE');
        if (isset($hash['DEPRECATED-VERSION'])) $hash->offsetGet('DEPRECATED-VERSION');
        
        $this->_findUnused($hash);
        
    }
    
    /**
     * Triggers errors for any unused keys passed in the hash; such keys
     * may indicate typos, missing values, etc.
     * @param $hash Instance of ConfigSchema_StringHash to check.
     */
    protected function _findUnused($hash) {
        $accessed = $hash->getAccessed();
        foreach ($hash as $k => $v) {
            if (!isset($accessed[$k])) {
                trigger_error("String hash key '$k' not used by adapter", E_USER_NOTICE);
            }
        }
    }
    
}