from mteb.models import ModelMeta
from mteb.models.instruct_wrapper import InstructSentenceTransformerModel
from mteb.models.model_meta import ScoringFunction
from mteb.types import PromptType

F2LLM_CITATION = """@article{2025F2LLM,
    title={F2LLM Technical Report: Matching SOTA Embedding Performance with 6 Million Open-Source Data},
    author={Ziyin Zhang and Zihan Liao and Hang Yu and Peng Di and Rui Wang},
    journal={CoRR},
    volume={abs/2510.02294},
    year={2025},
    url={https://doi.org/10.48550/arXiv.2510.02294},
    doi={10.48550/ARXIV.2510.02294},
    eprinttype={arXiv},
    eprint={2510.02294}
}"""

training_datasets = {
    "MSMARCO",
    "ArguAna",
    "SNLI",
    "MNLI",
    "ANLI",
    "PAQ",
    "SQuAD",
    "StackExchange",
    "NQ",
    "HotpotQA",
    "FEVER",
    "ELI5",
    "FiQA2018",
    "BioASQ",
    "NFCorpus",
    "MIRACLRetrieval",
    "MrTidyRetrieval",
    "SciFact",
    "TriviaQA",
    "COLIEE",
    "PubMedQA",
    "S2ORC",
    "AmazonQA",
    "SPECTER",
    "XSum",
    "CNNDM",
    "SentenceCompression",
    "StackExchangeDupQuestions",
    "QQP",
    "StackOverflowDupQuestions",
    "STS12",
    "STS22",
    "STSBenchmark",
    "AmazonCounterfactualClassification",
    "AmazonPolarityClassification",
    "ImdbClassification",
    "ToxicConversationsClassification",
    "CoLA",
    "AmazonReviewClassification",
    "Banking77Classification",
    "EmotionClassification",
    "MTOPIntentClassification",
    "MTOPDomainClassification",
    "MassiveScenarioClassification",
    "MassiveIntentClassification",
    "TweetSentimentExtractionClassification",
    "ArxivClusteringP2P",
    "ArxivClusteringS2S",
    "BiorxivClusteringP2P",
    "BiorxivClusteringS2S",
    "MedrxivClusteringP2P",
    "MedrxivClusteringS2S",
    "RedditClustering",
    "RedditClusteringP2P",
    "StackExchangeClustering",
    "StackExchangeClusteringP2P",
    "TwentyNewsgroupsClustering",
}

c2llm_training_datasets = {
    "CodeSearchNet",
    "CodeSearchNetRetrieval",
    "CodeSearchNetCCRetrieval",
    "CodeEditSearchRetrieval",
    "CodeFeedbackMT",
    "CodeFeedbackST",
    "CodeTransOceanContest",
    "CodeTransOceanDL",
    "COIRCodeSearchNetRetrieval",
    "CosQA",
    "StackOverflowQA",
    "SyntheticText2SQL",
    "AdvTrain",
}

prompts_dict = {
    "AmazonCounterfactualClassification": "Classify a given Amazon customer review text as either counterfactual or not counterfactual.",
    "Banking77Classification": "Given an online banking query, find the corresponding intents.",
    "ImdbClassification": "Classify the sentiment expressed in the given movie review text from the IMDB dataset.",
    "MTOPDomainClassification": "Classify the intent domain of the given utterance in task-oriented conversation.",
    "MassiveIntentClassification": "Given a user utterance as query, find the user intents.",
    "MassiveScenarioClassification": "Given a user utterance as query, find the user scenarios.",
    "ToxicConversationsClassification": "Classify the given comments as either toxic or not toxic.",
    "TweetSentimentExtractionClassification": "Classify the sentiment of a given tweet as either positive, negative, or neutral",
    "ArXivHierarchicalClusteringP2P": "Identify the main and secondary category of arXiv papers based on the titles and abstracts.",
    "ArXivHierarchicalClusteringS2S": "Identify the main and secondary category of arXiv papers based on the titles.",
    "BiorxivClusteringP2P.v2": "Identify the main category of bioRxiv papers based on the titles and abstracts.",
    "MedrxivClusteringP2P.v2": "Identify the main category of medRxiv papers based on the titles and abstracts.",
    "MedrxivClusteringS2S.v2": "Identify the main category of medRxiv papers based on the titles.",
    "StackExchangeClustering.v2": "Identify the topic or theme of StackExchange posts based on the titles.",
    "StackExchangeClusteringP2P.v2": "Identify the topic or theme of StackExchange posts based on the given paragraphs.",
    "TwentyNewsgroupsClustering.v2": "Identify the topic or theme of the given news articles.",
    "SprintDuplicateQuestions": "Retrieve duplicate questions from Sprint forum.",
    "TwitterSemEval2015": "Retrieve tweets that are semantically similar to the given tweet.",
    "TwitterURLCorpus": "Retrieve tweets that are semantically similar to the given tweet.",
    "AskUbuntuDupQuestions": "Retrieve duplicate questions from AskUbuntu forum.",
    "MindSmallReranking": "Retrieve relevant news articles based on user browsing history.",
    "ArguAna": "Given a claim, find documents that refute the claim.",
    "CQADupstackGamingRetrieval": "Given a question, retrieve questions that are semantically equivalent.",
    "CQADupstackUnixRetrieval": "Given a question, retrieve questions that are semantically equivalent.",
    "ClimateFEVERHardNegatives": "Given a claim about climate change, retrieve documents that support or refute the claim.",
    "FEVERHardNegatives": "Given a claim, retrieve documents that support or refute the claim.",
    "FiQA2018": "Given a financial question, retrieve passages that answer the question.",
    "HotpotQAHardNegatives": "Given a multi-hop question, retrieve passages that answer the question.",
    "SCIDOCS": "Given a scientific paper title, retrieve paper abstracts that are cited by the given paper.",
    "TRECCOVID": "Given a query on COVID-19, retrieve documents that answer the query.",
    "Touche2020Retrieval.v3": "Given a question, retrieve passages that answer the question.",
    "BIOSSES": "Retrieve semantically similar text.",
    "SICK-R": "Retrieve semantically similar text.",
    "STS12": "Retrieve semantically similar text.",
    "STS13": "Retrieve semantically similar text.",
    "STS14": "Retrieve semantically similar text.",
    "STS15": "Retrieve semantically similar text.",
    "STS17": "Retrieve semantically similar text.",
    "STS22.v2": "Retrieve semantically similar text.",
    "STSBenchmark": "Retrieve semantically similar text.",
    "SummEvalSummarization.v2": "Given a news summary, retrieve other semantically similar summaries.",
}


c2llm_prompts_dict = {
    "CodeEditSearchRetrieval": {
        "query": "Retrieve the diff code that relevant the following query:\n",
        "document": "Retrieved Answer:",
    },
    "CodeSearchNetRetrieval": {
        "query": "Retrieve the code that solves the following query:\n",
        "document": "Retrieved Answer:",
    },
    "AppsRetrieval": {
        "query": "Given a problem description from a programming contest, retrieve code examples that can assist in solving it.\n",
        "document": "Retrieved Answer:",
    },
    "CodeFeedbackMT": {
        "query": "Given a multi-turn conversation history that includes both text and code, retrieve relevant multi-modal answers composed of text and code that address the ongoing discussion.\n",
        "document": "Retrieved Answer:",
    },
    "CodeFeedbackST": {
        "query": "Given a single-turn question composed of text and code, retrieve suitable answers that also mix text and code to provide helpful feedback.\n",
        "document": "Retrieved Answer:",
    },
    "CodeSearchNetCCRetrieval": {
        "query": "Given an initial code segment, retrieve the subsequent segment that continues the code.\n",
        "document": "Retrieved Answer:",
    },
    "CodeTransOceanContest": {
        "query": "Given a Python code snippet, retrieve its semantically equivalent version written in C++.\n",
        "document": "Retrieved Answer:",
    },
    "CodeTransOceanDL": {
        "query": "Given a Python code snippet, retrieve its semantically equivalent version written in C++.\n",
        "document": "Retrieved Answer:",
    },
    "COIRCodeSearchNetRetrieval": {
        "query": "Given a code snippet, retrieve its corresponding document string that summarizes its functionality.\n",
        "document": "Retrieved Answer:",
    },
    "CosQA": {
        "query": "Given a query from a web search, retrieve code that is helpful in addressing the query.\n",
        "document": "Retrieved Answer:",
    },
    "StackOverflowQA": {
        "query": "Given a question combining text and code, retrieve relevant answers that also contain both text and code snippets and can address the question.\n",
        "document": "Retrieved Answer:",
    },
    "SyntheticText2SQL": {
        "query": "Given a natural language question, retrieve SQL queries that serve as appropriate responses.\n",
        "document": "Retrieved Answer:",
    },
}

c2llm_languages = [
    "eng-Latn",
    "zho-Hans",
    "python-Code",
    "javascript-Code",
    "go-Code",
    "ruby-Code",
    "java-Code",
    "php-Code",
]

c2llm_loader_kwargs = dict(
    trust_remote_code=True,
    prompts_dict=c2llm_prompts_dict,
    apply_instruction_to_passages=True,
    max_seq_length=2048,
    padding_side="left",
)


def instruction_template(
    instruction: str, prompt_type: PromptType | None = None
) -> str:
    if not instruction or prompt_type == PromptType.document:
        return ""
    if isinstance(instruction, dict):
        if prompt_type is None:
            instruction = "Given a web search query, retrieve relevant passages that answer the query"
        else:
            instruction = instruction[prompt_type]
    return f"Instruct: {instruction}\nQuery: "


F2LLM_0B6 = ModelMeta(
    loader=InstructSentenceTransformerModel,
    loader_kwargs=dict(
        instruction_template=instruction_template,
        prompts_dict=prompts_dict,
        apply_instruction_to_passages=False,
        add_eos_token=True,
        max_seq_length=8192,
    ),
    name="codefuse-ai/F2LLM-0.6B",
    model_type=["dense"],
    languages=["eng-Latn"],
    open_weights=True,
    revision="36416618b83d4bd84a8ca30c2ee01ed518f9f2e7",
    release_date="2025-09-18",
    n_parameters=596049920,
    n_embedding_parameters=155582464,
    memory_usage_mb=1137,
    embed_dim=1024,
    license="apache-2.0",
    max_tokens=8192,
    reference="https://huggingface.co/codefuse-ai/F2LLM-0.6B",
    similarity_fn_name="cosine",
    framework=["Sentence Transformers", "PyTorch", "safetensors", "Transformers"],
    use_instructions=True,
    public_training_code="https://github.com/codefuse-ai/F2LLM",
    public_training_data="https://huggingface.co/datasets/codefuse-ai/F2LLM",
    training_datasets=training_datasets,
    citation=F2LLM_CITATION,
)

F2LLM_1B7 = ModelMeta(
    loader=InstructSentenceTransformerModel,
    loader_kwargs=dict(
        instruction_template=instruction_template,
        prompts_dict=prompts_dict,
        apply_instruction_to_passages=False,
        add_eos_token=True,
        max_seq_length=8192,
    ),
    name="codefuse-ai/F2LLM-1.7B",
    model_type=["dense"],
    languages=["eng-Latn"],
    open_weights=True,
    revision="fdce0e09655f42cea26f7f66f5a70cd4507ea45c",
    release_date="2025-09-18",
    n_parameters=1_720_574_976,
    n_embedding_parameters=311164928,
    memory_usage_mb=3282,
    embed_dim=2560,
    license="apache-2.0",
    max_tokens=8192,
    reference="https://huggingface.co/codefuse-ai/F2LLM-1.7B",
    similarity_fn_name="cosine",
    framework=["Sentence Transformers", "PyTorch", "safetensors", "Transformers"],
    use_instructions=True,
    public_training_code="https://github.com/codefuse-ai/F2LLM",
    public_training_data="https://huggingface.co/datasets/codefuse-ai/F2LLM",
    training_datasets=training_datasets,
    citation=F2LLM_CITATION,
)

F2LLM_4B = ModelMeta(
    loader=InstructSentenceTransformerModel,
    loader_kwargs=dict(
        instruction_template=instruction_template,
        prompts_dict=prompts_dict,
        apply_instruction_to_passages=False,
        add_eos_token=True,
        max_seq_length=8192,
    ),
    name="codefuse-ai/F2LLM-4B",
    model_type=["dense"],
    languages=["eng-Latn"],
    open_weights=True,
    revision="9fe95901ed2b6b59dd7673d6e93c9d76766a1e25",
    release_date="2025-09-18",
    n_parameters=4022468096,
    n_embedding_parameters=388956160,
    memory_usage_mb=7672,
    embed_dim=2560,
    license="apache-2.0",
    max_tokens=8192,
    reference="https://huggingface.co/codefuse-ai/F2LLM-4B",
    similarity_fn_name="cosine",
    framework=["Sentence Transformers", "PyTorch", "safetensors", "Transformers"],
    use_instructions=True,
    public_training_code="https://github.com/codefuse-ai/F2LLM",
    public_training_data="https://huggingface.co/datasets/codefuse-ai/F2LLM",
    training_datasets=training_datasets,
    citation=F2LLM_CITATION,
)

C2LLM_0B5 = ModelMeta(
    loader=InstructSentenceTransformerModel,
    loader_kwargs=c2llm_loader_kwargs,
    name="codefuse-ai/C2LLM-0.5B",
    revision="f08c18be03de42c6e388948a1804d4b271a953a2",
    release_date="2025-12-22",
    languages=c2llm_languages,
    n_parameters=497252096,
    n_embedding_parameters=136134656,
    memory_usage_mb=948.0,
    max_tokens=32768,
    embed_dim=896,
    license="apache-2.0",
    open_weights=True,
    public_training_code=None,
    public_training_data=None,
    framework=["PyTorch", "Sentence Transformers", "Transformers", "safetensors"],
    reference="https://huggingface.co/codefuse-ai/C2LLM-0.5B",
    similarity_fn_name=ScoringFunction.COSINE,
    use_instructions=True,
    training_datasets=c2llm_training_datasets,
    adapted_from=None,
    superseded_by=None,
    modalities=["text"],
    is_cross_encoder=None,
    citation=None,
    contacts=None,
)

C2LLM_7B = ModelMeta(
    loader=InstructSentenceTransformerModel,
    loader_kwargs=c2llm_loader_kwargs,
    name="codefuse-ai/C2LLM-7B",
    revision="c1dc16d6d64eb962c783bfb36a6d9c2f24a86dca",
    release_date="2025-12-22",
    languages=c2llm_languages,
    n_parameters=7667028992,
    n_embedding_parameters=544997376,
    memory_usage_mb=14624.0,
    max_tokens=32768,
    embed_dim=3584,
    license="apache-2.0",
    open_weights=True,
    public_training_code=None,
    public_training_data=None,
    framework=["PyTorch", "Sentence Transformers", "Transformers", "safetensors"],
    reference="https://huggingface.co/codefuse-ai/C2LLM-7B",
    similarity_fn_name=ScoringFunction.COSINE,
    use_instructions=True,
    training_datasets=c2llm_training_datasets,
    adapted_from=None,
    superseded_by=None,
    modalities=["text"],
    is_cross_encoder=None,
    citation=None,
    contacts=None,
)
