package ru.yandex.wmconsole.verification;

import java.io.IOException;
import java.net.URL;

import net.htmlparser.jericho.EndTag;
import net.htmlparser.jericho.Segment;
import net.htmlparser.jericho.StartTag;
import net.htmlparser.jericho.StreamedSource;
import org.apache.http.Consts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ru.yandex.wmconsole.data.VerificationStateEnum;
import ru.yandex.wmconsole.data.info.UsersHostsInfo;
import ru.yandex.wmtools.common.sita.SitaUrlFetchResponse;

/**
 * @author aherman
 */
public class JerichoMetaTagChecker implements MetaTagVerifier.MetaTagChecker {
    private static final Logger log = LoggerFactory.getLogger(JerichoMetaTagChecker.class);

    @Override
    public UsersHostsInfo checkMetatag(UsersHostsInfo verInfo, URL urlAddress,
            SitaUrlFetchResponse sitaUrlFetchResponse)
    {
        try {
            StreamedSource source = new StreamedSource(sitaUrlFetchResponse.getDocumentContent(Consts.ISO_8859_1));
            boolean inHeadTag = false;
            String expectedVerificationUid = VerificationIdentifier.valueOf(verInfo.getVerificationUin()).toString();

            for (Segment segment : source) {
                if (segment instanceof StartTag) {
                    StartTag startTag = (StartTag) segment;
                    if ("body".equalsIgnoreCase(startTag.getName())) {
                        break;
                    } else if ("head".equalsIgnoreCase(startTag.getName())) {
                        inHeadTag = true;
                    } else if (inHeadTag && "meta".equalsIgnoreCase(startTag.getName())) {
                        String name = startTag.getAttributeValue("name");
                        if (!"yandex-verification".equalsIgnoreCase(name)) {
                            log.debug("Jericho. Found unknown meta-tag: name=" + name);
                            continue;
                        }
                        String contentValue = startTag.getAttributeValue("content");
                        if (expectedVerificationUid.equalsIgnoreCase(contentValue)) {
                            log.info(
                                    "Jericho. Checking meta-tag: Verification info in meta tag found successfully " + urlAddress);
                            return UsersHostsInfo.createVerifiedNow(verInfo);
                        } else {
                            log.debug("Jericho. Unknown verification uid: found content=" + contentValue + " expected=" + expectedVerificationUid + " " + urlAddress);
                        }
                    }
                } else if (segment instanceof EndTag) {
                    if ("head".equalsIgnoreCase(((EndTag) segment).getName())) {
                        inHeadTag = false;
                    }
                }
            }

            String errorMessage = "Jericho. Valid meta-tag not found: " + urlAddress;
            log.info(errorMessage);
            return UsersHostsInfo
                    .createNotVerifiedNow(verInfo, VerificationStateEnum.META_TAG_VERIFICATION_TAG_NOT_FOUND,
                            errorMessage);
        } catch (IOException e) {
            String verifyFaultLog = "Jericho. Checking meta-tag: Not verified: IOException while reading file with meta-tag: " + urlAddress + " " + e;
            log.debug(verifyFaultLog);
            return UsersHostsInfo
                    .createNotVerifiedNow(verInfo, VerificationStateEnum.META_TAG_IO_EXCEPTION, verifyFaultLog);
        } catch (Exception e) {
            String verifyFaultLog = "Jericho. Checking meta-tag: Not verified: Exception while reading file with meta-tag: " + urlAddress + " " + e;
            log.debug(verifyFaultLog);
            return UsersHostsInfo
                    .createNotVerifiedNow(verInfo, VerificationStateEnum.META_TAG_PARSER_EXCEPTION, verifyFaultLog);
        }
    }
}
